我在某个地方读到(抱歉,找不到链接),For...In循环不建议用于数组。 这里说: http://www.openjs.com/articles/for_loop.php 它是用于关联数组的,并且在 http://www.w3schools.com/js/js_loop_for_in.asp 中也说其用于迭代对象的所有属性(没有说可以用于数组)。我不知道该相信谁。 我不想让这个问题变成辩论。我只想知道如果我在代码中使用它是否会有意外的副作用。 谢谢!
我在某个地方读到(抱歉,找不到链接),For...In循环不建议用于数组。 这里说: http://www.openjs.com/articles/for_loop.php 它是用于关联数组的,并且在 http://www.w3schools.com/js/js_loop_for_in.asp 中也说其用于迭代对象的所有属性(没有说可以用于数组)。我不知道该相信谁。 我不想让这个问题变成辩论。我只想知道如果我在代码中使用它是否会有意外的副作用。 谢谢!
数组是一个对象,数组元素只是将数字索引转换为字符串的属性。例如,arr[123]指的是数组对象arr中的一个名为“123”的属性。
for ... in
结构适用于所有对象,不仅仅是数组,这就导致了混淆。
当有人对数组使用for ... in
时,大多数情况下程序员想要迭代所有的元素,甚至很可能按顺序迭代。例如,如果数组保存了一些数字,则程序员最有可能想要迭代一系列数字。这个语义与其他编程语言中数组迭代非常相似,因此很容易让人混淆。
在JavaScript中,这个结构不会按顺序迭代数组元素。它会迭代所有数组的属性名称(包括继承的原型函数的名称、添加到它的任何属性、添加到它的任何其他非元素属性等),而且没有顺序可言。在早期的浏览器中,它甚至可以找到属性length
,尽管在最近的浏览器中,为了避免这种情况发生,这些属性现在被定义为隐藏属性。
对于上面的整数数组,你得到的不是一系列数字,而是一系列文本字符串。不是元素值,而是属性名称(这些名称只是没有顺序的数字索引)。如果数组中存储的元素恰好是相似的数字值,它会让所有人都感到困惑。
因此,你不应该这么做。不应该使用一个看起来像做明显事情的语言结构,但实际上做的事情完全不同。这会创建非常难以找到的非常难以理解的错误。
for ... in
语法来迭代对象的属性;因此,对于数组来说,除了元素之外,也会迭代所有该数组对象的属性。通常,数组对象只有与其键相对应的属性,但如果另一个脚本修改了Array.prototype
(例如某些框架),那么添加的方法/属性也会意外地显示在迭代中。for ... in
的示例,它运行良好,我必须因为其他原因改变了我的JS(可能是原型的问题)。 - Cameron使用for(... in ...)
迭代数组将无法获取数字键,而是获取字符串值。
它将获取在原型上定义的属性,因此如果任何代码扩展了Array
,例如通过执行以下操作:
Array.prototype.each = ...;
那么您将看到属性each
。
不能保证以数组索引顺序获取属性。例如,尝试迭代:
var arr = []
arr[1] = 1;
arr[0] = 0;
0
之前得到1
。[0,,,3]
1
或 2
的值。
array = {}; array[42] = 'foo'; array["42"] // => 'foo' (!)
。对于数字来说,这并不太疯狂,但对于对象(我希望能够将其用作“关联数组”中的键),它就行不通了:var key1 = {name: 'Gareth'}, key2 = {}, array = {}; array[key1] = 'awesome'; array[key2] // => 'awesome' (!)
在这种情况下,“键”都具有相同的.toString()
,因此设置了相同的属性。 - Gareth