2015-06-14 45 views
0
A = [1,2,3,4,5]; 
for (var i in A) { 
    if (A[i] == 4) A.splice(i,1), A.push(7); 
    if (A[i] == 2) A.splice(i,1), A.push(0); 
    if (A[i] == 7) console.log('seven'); 
    if (A[i] == 0) console.log('zero'); 
} 
console.log(A); 

这似乎工作,但我不知道执行for(.. in ..)循环的细节,以确保它在大多数情况下是安全的。修改(..in ..)循环中的数组是否安全?

See also the paired question about an object modification

+4

用'for..in'完成迭代数组不是个好主意。 – Teemu

+1

[ECMA 262 - 'for-in'声明](http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4)。在先前的迭代完成之后,一次检索一个属性。所以,如果你问是否有可能修改对象,使循环无限延伸,是的,这是可能的。 –

+0

*有可能吗?*是的。 *安全吗?*是的。 *这是一种很好的做法吗?*不,因为您所指的索引很容易迷路。 –

回答

0

这是完全安全的改变意义上的对象,你不会得到浏览器抱怨任何改变阵列。请注意,在你的例子中,如果你看到“七,零”,只是“七”,只是“零”,或者什么也没有被打印,那么它仍然是有效的行为。

一方面,浏览器必须确保在被访问之前被删除的属性未被枚举。在另一方面,浏览器可以自由:

  • 枚举新的属性或让他们跳出循环
  • 以任何顺序枚举属性。

这就是为什么它不是安全使用for ... in来遍历数组,当你依靠索引/顺序。索引被视为可枚举的属性,可以使用与对象属性相同的机制枚举(对迭代顺序没有期望)。