为什么JavaScript是For… In循环不推荐用于数组? [重复]

    这个问题在这里已有答案:                           为什么使用“ for… in”数组迭代一个坏主意?                                      26个答案                                    
已邀请:
数组是一个对象,数组元素只是将数字索引转换为字符串的属性。例如,arr [123]引用数组对象arr中的属性“123”。
for ... in
构造适用于所有对象,而不仅仅是数组,这是造成混淆的原因。 当有人
for ... in
一个数组时,程序员通常只想迭代所有元素,甚至最有可能按顺序迭代。例如,如果数组包含一堆数字,那么程序员很可能打算迭代一个数字流。语义与其他编程语言中的数组迭代非常相似,因此很容易混淆。 在JavaScript中,此构造不会按顺序迭代数组元素。它迭代所有数组的属性名称(包括继承的原型函数的名称,添加到它的任何属性,添加到它的任何其他非元素属性等),而不是按顺序。在早期的浏览器中,它甚至会找到属性
length
,尽管在最近的浏览器中,这些属性现在被定义为隐藏在这个确切的原因 - 人们不断绊倒它! 使用上面的整数数组,您不会获得数字流,而是获得文本字符串流。而不是元素值,而是属性的名称(它们只是不以任何顺序排列的数字索引)。如果他/她来自另一种编程语言,这很可能不是程序员的意思。如果存储在数组中的元素碰巧是类似的数值,那么它会让每个人都感到困惑。 这就是你不应该这样做的原因。你不应该使用看起来像它做一些明显的事情的语言结构,但实际上做的事情是完全不同的。它会产生非常模糊且很难找到的错误。     
我已经在几个浏览器(FireFox 3,Opera 9,IE6,IE9 beta,Chrome)中测试了数组迭代,它运行良好;我似乎记得一些跨浏览器的不兼容性,但我必须弄错。 但仍有一点需要注意: 正如您所提到的,
for ... in
语法用于迭代对象的属性;因此,对于数组,该数组对象的所有属性也将与元素一起迭代。通常,数组对象只具有与其中的键对应的属性,但如果另一个脚本修改了
Array.prototype
(例如某个框架),则添加的方法/属性也会意外地出现在迭代中。     
Prototype.js库文档中给出了几个很好的理由: http://www.prototypejs.org/api/array 基本上,使用for ... in迭代一个数组是很脆弱的,因为任何其他代码都可以为Array原型添加属性,然后它将成为每个数组对象的可枚举属性。     
使用
for(... in ...)
迭代数组不会得到数字键,它会获得字符串值。 它将为您提供原型上定义的属性,因此,如果任何代码延伸
Array
,例如通过做:
Array.prototype.each = ...;
然后你会看到属性
each
。 没有任何人会以数组索引顺序获取属性。例如。尝试迭代
var arr = []
arr[1] = 1;
arr[0] = 0;
在很多浏览器上,你会在
0
之前得到
1
。 并且您无法保证获得所有指数。尝试迭代
[0,,,3]
你不会得到指数
1
2
。     

要回复问题请先登录注册