for(var i in yourObjects){...}和.hasOwnProperty()...讨论

时间:2012-09-26 03:49:05

标签: javascript

var yourObjects = [ 

{ object: {obj1:"aa"}, direction: 'top' },
{ object: "obj2", direction: 'left' }, 
{ object: "obj3", direction: 'bottom' }

]; 

for (var i in yourObjects) { alert(i); }

对此进行了长时间的讨论。 使用for in迭代Object将返回Object的所有属性和方法,因此通常应使用.hasOwnProperty()方法。但是当我们迭代一个数组时,实际上for in会迭代数组的索引(如果它是一个关联数组,则重复它们)。我在我拥有的所有浏览器中都尝试过它。但是当在jsfiddle中尝试时......它不一样......返回了数组所有的方法。

所以我的任务是:使用for in迭代数组是否安全?

在浏览器和jsfiddle中尝试此代码,并告诉我您的想法。

1 个答案:

答案 0 :(得分:7)

不在数组上使用for-in的原因不止一个。

请记住,在JavaScript中,Array只是一种Object,因此对数组执行for-in与在普通对象上执行for-in没有什么不同。

在你的jsFiddle中,你可能在左边选择了一个扩充Array.prototype的库,这将是这些方法的来源。

但还有另一个原因。 for-in不保证枚举属性的顺序。因为没有约束,它可以不按顺序枚举你的索引,并且完全符合ECMAScript。

此外,还有类似数组的集合,如NodeLists也不应使用for-in,因为它们包含除DOM元素外还可以枚举的默认属性。

简单的事实是,在JavaScript中,for-in不适合基于索引的枚举。


对于对象,只有在特定需要时才需要使用hasOwnProperty

有人建议必须在所有对象上使用它。这是一种极端偏执的心态。该方法是一种应该在那些有意义的 narrow 情况下使用的守卫。

大多数情况下,只要您遵循良好的编程习惯,使用它就没有任何意义。这包括不在Object.prototype上放置可枚举属性。制作编程环境只是一个简单而合理的要求。

有意义的时间是在枚举从自定义构造函数创建的对象时,该构造函数的.prototype扩展了可枚举属性。在这种情况下,它是一个适当的使用保护。

在普通物体上使用它是一种大规模的过度杀伤,当一种更合理的方法是要求你的环境不会改变Object.prototype