JavaScript中的“for ... in”循环是否总是不好?

3
我有一个问题,我正在尝试使用一个数组,但是我不认为它会有效。我想要一个对象列表,每个对象都有一个唯一的ID,并且我想要能够轻松地引用特定的对象,而不必通过搜索ID来循环遍历数组。
如果我使用一个对象,我可以很容易地将唯一的ID作为键,对象作为值。然而,如果我使用一个对象而不是一个数组,我将不得不使用一个“for ... in”循环,我知道如果使用我的代码的人扩展了Object.prototype,就会出现问题。
所以这是我的问题:
人们真的经常扩展Object.prototype吗?我应该警惕使用它吗?还有其他原因我不想使用“for ... in”循环吗?
另一方面,循环遍历数组查找唯一的ID的性能损失是否非常小,我不用担心?
(记录一下,这个数组可能只有很少的元素,但我会非常频繁地访问它。另外,我正在编写的代码将是一个jQuery插件,所以我无法控制其他人与之组合使用的糟糕代码。)
更新:
根据@nnnnnn的建议,我设置了一个jsperf测试,以下是结果: http://jsperf.com/accessing-object-properties-vs-iterating-over-arrays 基本上,虽然对象方式稍微快一点,但差别微不足道。尽管如此,使用带有hasOwnProperty的for...in似乎更加清晰。

1
不是的。只有在使用该结构覆盖数组并期望进行其他语言中的for-each时,它才通常会出现问题。(答案涵盖了其余部分。) - user166390
3个回答

5

即使有人扩展了原型,您也可以使用hasOwnProperty属性来排除这些成员。 这正是Sugar.js推荐的做法

var s = 'cat', key;
for(key in s) {
  if(s.hasOwnProperty(key)) {
    console.log(key);
  }
}

现在根据Sugar的说法,for..in循环已经成为对象字面量的标准循环方式,但你也可以使用像jQuery中的$.each或Underscore.js中的_.each这样的迭代器。请注意,保留了HTML标签。

hasOwnProperty 只能在继承自 Object 的对象上使用。我知道我可以这样做,但我真的希望找到一个不涉及创建新“类”的解决方案。我也希望从性能的角度回答我的关于数组和对象迭代的问题。 - Philip Walton
2
@Philip Walton - 等等,什么?你有不继承自“Object”的对象吗?为什么认为需要创建一个新的“类”来使用.hasOwnProperty() - nnnnnn
@nnnnnn 哎呀!谢谢你指出来。我错误地认为 hasOwnProperty 不适用于对象字面量,而只适用于从根 Object 类继承的其他对象。 - Philip Walton

2
你可以在for..in循环中使用hasOwnProperty方法来区分原型链上的内容和分配给你的对象的内容。
或者你可以保留分配给特定对象的“键”的列表。

2
这是我的问题:
人们真的经常扩展 Object.prototype,以至于我使用它时应该小心吗?还有其他原因不想使用 for...in 循环吗?
不,这并不常见,但确实会发生。你应该仍然使用 for...in 循环,但像其他答案中所示,结合使用 .hasOwnProperty()
我想不出任何理由不要在对象上使用 for..in(显然不要在数组上使用它)。
另一方面,循环遍历数组查找唯一 ID 的性能损失如此之小,以至于我不必担心吗?
嗯,你提到你的数组不会有很多元素,但我仍认为,即使它表现良好,它也会不必要地使你的代码复杂化,因为对于对象来说,你根本不需要这样做。另一方面,使用 .hasOwnProperty() 是一个微小的复杂化,实际上成为每个 for..in 的语法的一部分。
你可以在这里设置性能测试:http://jsperf.com/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接