2

我添加了一些有用的助手Array(比如toSource()Opera)。现在for..in返回具有正常属性的函数。

我现在正在使用for..in,因为代码更容易阅读。而且它是js的原生函数,所以必须更快。

但是在循环中添加类型检查可以更容易地使用 classic for(;;)

有什么方法可以避免for..in枚举函数吗?

跨浏览器工作不是很有必要(必须在 Opera 中工作),但速度很重要。

谢谢你。


编辑:
是否有能力避免for..in从任何 Object 枚举函数或自定义属性?

4

6 回答 6

5

永远不应该使用 for..in 循环来遍历数组元素。for..in 设计用于迭代properties,并且应该只用于此目的,这正是您刚刚描述的原因。许多库会修改数组、日期等原型,因此您不应依赖 for..in 仅迭代数组元素。使用 for(;;) 方法,它保证做你想做的事。而且它并不比 for..in 循环快,因为它也是 JavaScript 原生的。

有关更多信息,请在prototype.js库中阅读。

于 2009-11-27T16:03:15.730 回答
3

是的,但它仅适用于 JavaScript 1.7+。Opera 只有有限的 JavaScript 1.7 支持,其中包括对解构赋值的非常基本的支持,因此这在 Opera 中不起作用,但在 Firefox 中会起作用。

此实现允许安全地使用for [each](item in array)

Array.prototype.__iterator__ = function (flag) {
    var len = this.length, i = 0;

    for (; i < len; i++) {
        yield flag ? i : this[i];
    }
};
于 2009-11-27T17:29:03.827 回答
2

正如其他人所说,您不应该使用 for..in 来迭代数组。它比使用 for(;;) 慢。

如果您关心性能,您还应该缓存数组的长度,如:

for (var i=0, len=arr.length; i<len; i++) 
{
  ... 
}

仅用于 for..in 迭代对象的属性。要排除继承的属性,请使用 hasOwnProperty() 方法:

for (var prop in object)
{
  // Don't include properties inherited from the prototype chain
  if (object.hasOwnProperty(prop))
  {
    ...
  }
}
于 2009-11-27T16:34:45.077 回答
2

现在有了另一个支持 ES5 的选项,它允许您定义不可枚举的属性!应该可以(虽然我没有测试过)做这样的事情:

Object.defineProperty( Array.prototype, "myNewMethod", {
   value: function(){},
   writable: true,
   enumerable: false, /* this controls for..in visibility */
   configurable: true
});
于 2012-01-03T23:35:21.333 回答
1

您所描述的正是您使用的原因

for (var i=0; i<arr.length; i++) { ... }

代替:

for (var item in arr) { ... }

因为他们是不同的。

如果您不希望在第二种形式中获得所有成员,而只需要索引元素,则使用第一种形式。

于 2009-11-27T16:02:57.263 回答
0

编辑:由于@Bergi 的评论,纠正了错误的 typeof 用法

关于迭代(非常)稀疏数组时的性能的好点 - 我建议也许在循环中使用 isNaN(parseInt()) 可以让你只找到数组元素:

for( var propertyName in myArray){
    if( !isNaN(parseInt(propertyName)) ){ /* probably array element */ }
}

我不知道什么比 hasOwnProperty() 和上述方法表现更好。你只需要用一个非常大的数组迭代它 10000 次或类似的东西来测量它。如果您进行一些性能测量,结果会很有趣,所以请分享!:)

于 2009-12-06T20:09:40.937 回答