如何为...添加“不触发”的新数组方法?

时间:2015-09-09 11:25:11

标签: javascript arrays

当使用for..in循环以及我添加到array.prototype的函数时,for..in也循环遍历所有这些函数。

The JavaScript for/in statement loops through the properties of an object

但是如何在没有在for..in?

中触发的情况下添加到数组原型中

示例代码:

Array.prototype.sum = function (prop) {
    // Do something
}

for (item in myArray) {
    // Would actually loop myArray.length times + 1 for the 'sum'
}

我正在使用一个使用for..in循环的库,我无法改变它。

2 个答案:

答案 0 :(得分:3)

使用Object.definePropert y,您可以向Array.prototype添加内容,而不是enumerable,因此不能成为for-in循环中的目标。

尽管如此,作为最后的手段,for-in应该尽可能避免。

// This appears in for-in
Array.prototype.sum = function (prop) {
    // Do something
}

// This won't appears in for -in loop.
Object.defineProperty(Array.prototype, 'add', {
  value: function() {
    console.log('OOPSS');
  },
  
  // enumerable is default to false, and it decide whether the attr would be  a target
  // in for-in loop or not.
  enumerable: false
});

var myArray = [1, 2, 3];

for (item in myArray) {
  console.log(item);
    // Would actually loop myArray.length times + 1 for the 'sum'
}

// Check `add` did added to array.prototype.
myArray.add();

答案 1 :(得分:3)

  

但是如何在没有在for..in?

中触发的情况下添加到数组原型中

通过Object.defineProperty将其添加为不可枚举的属性。不可枚举是默认值,因此:

Object.defineProperty(Array.prototype, "sum", {
    value: function() {
        // ...implementation of sum
    }
});

...但如果我们想要明确,我们就有enumerable: false

Object.defineProperty(Array.prototype, "sum", {
    enumerable: false, // <== Not necessary, false is the default
    value: function() {
        // ...implementation of sum
    }
});

直播示例:

&#13;
&#13;
Object.defineProperty(Array.prototype, "sum", {
  value: function() {
    return this.reduce(function(acc, value) {
      return acc + value;
    }, 0);
  }
});

var a = [1, 2, 3];
snippet.log("a.sum() = " + a.sum());
var key;
for (key in a) {
  snippet.log("key = " + key);
}
snippet.log("Note that 'sum' did not show up as a key");
&#13;
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
&#13;
&#13;

所有现代浏览器都支持Object.defineProperty,这是2009年发布的第5版规范的一部分。 IE8不,因为它早于规范。< / p>

附注:我建议不要使用for-in循环遍历数组,无论是否向Array.prototype(或数组本身)添加非条目属性。我推荐this answer中的各种替代方案。但是你已经说过你正在使用一个可以执行它的库并且没有进行必要的hasOwnProperty检查(这使它成为一个编写得不好的库)而且无法改变那就是......以上是您添加Array.prototype的方式,但for-in中没有添加内容。