是否可以在每次创建数组时执行某个功能?

时间:2015-08-27 12:29:32

标签: javascript arrays

创建数组时,我需要自动在该数组上调用一个函数。我认为这可能会以某种方式使用Array的原型/构造函数,但我对如何解决这个问题感到茫然。

所以我有一个数组,我初始化了:

var arr = [1, 2, 3];

现在让我们说我有这样的功能:

Array.prototype.objectArray = function() {
    var result = this.every(function(elem) {
        return typeof elem == "object";
    });
    this.isObjectArray = result;
}

因此,在这种情况下,调用此数组上的函数会将其isObjectArray参数指定给false

但是,我想要的是每次自动创建数组时,此函数都会在数组上运行,因此默认情况下每个数组都设置了isObjectArray属性。这可能吗?

提前致谢!

3 个答案:

答案 0 :(得分:5)

据我所知,这是不可能的,但你可以定义一个懒惰地计算数组是否只包含对象的函数:

Array.prototype.isObjectArray = function () {
  if (typeof(this.__isObjectArray) === 'undefined') {
    this.__isObjectArray = this.every(function(elem) {
      return typeof elem == "object";
    });
  }
  
  return this.__isObjectArray;
};


var a = [1, 2, 3];
var b = [[], {}];

alert("a: " + a.isObjectArray() + ", b: " + b.isObjectArray());

上面的代码只进行一次计算(第一次请求),在后续调用中只返回已计算的值。

此外,如果您创建的数组未调用isObjectArray(),则计算永远不会完成。

答案 1 :(得分:1)

没有。这可以通过覆盖Array在EcmaScript 3下实现,但这会打开一些令人讨厌的安全漏洞,如Jeremiah Grossman's contact list exfiltration attack against Gmail,因此不太可能引入任何类似的功能。

如果攻击者可以让用户访问某个页面,那么他们可以执行以下操作:

<script>
var arrayStolenFromJSONWebAPI;
var originalArray = Array;
Array = function () {
  var arr = new originalArray();
  originalArray.prototype.push.apply(arr, arguments);
  if (!arrayStolenFromJSONWebAPI) {
    arrayStolenFromJSONWebAPI = arr;
  }
  return arr;
}
</script>
<!-- XSRF attack that loads JSON requested with user's cookies -->
<script src="http://foo.com/web_api_in_same_origin_that_returns_json"></script>
<script>
exfiltrate(arrayStolenFromJSONWebAPI);
</script>

答案 2 :(得分:0)

虽然@ w0lf已经很好地回答了我的问题,但@MatteoTassinari对此评论有很多赞成:

  

创建一个&#34;工厂&#34;将数组作为参数然后对其执行任何操作的函数。

所以我想我会查看工厂并用一个问题回答我的问题,因为任何人都可以看到可能和我在工厂一样感兴趣的问题。这就是我想出的:

function arrayFactory(arr){
    var result = arr.every(function(elem) {
        return typeof elem == "object";
    });
    arr.isObjectArray = result;
    return arr;
}

var arr = arrayFactory([1, 2, 3]);
console.log(arr.isObjectArray);     //false

基本上,&#34;工厂&#34; function是任何只返回一个新对象的函数 - 在我的例子中是数组,我在工厂中通过向其添加isObjectArray变量进行变异。简单!