2

我刚刚尝试了for...inJavascript 中的语句。

这没有错误:

var images = document.getElementsByTagName('img');

for(x in images){
    document.write(images[x]) + " ");
}

但是,这做了它应该做的,但在 FF 错误控制台中给出了一个错误。

for(x in images){
    images[x].style.visibility="visible";
}

这让我很好奇发生了什么事。

这样做:

for(x in images){
    document.write(x);
}

...给了我这个:

01234567891011121314151617lengthitemnamedItem

最后有什么?我认为这使得document.images/document.getElementsByTagName('img')数组不适合与for...in语句一起使用,因为最后 x 的值与图像不对应?也许for循环更好?

4

3 回答 3

5

不要使用for ... in循环遍历数组。使用索引:

for (var i = 0; i < arr.length; ++i) {
  // images[i] ...
}

构造for ... in没有,只是不是你想做的;它适用于您想要遍历对象的所有属性时。数组是对象,除了语义上有趣的索引元素之外还有其他属性。

(实际上返回getElementsByTagName的并不是真正的数组;它是一个节点列表。但是,您可以将它视为一个数组,它通常可以正常工作。同样的基本警告for ... in在任何情况下都适用。)

于 2010-09-06T16:35:45.253 回答
1

for..in不循环遍历数组的索引,它循环遍历对象的可枚举属性名称。碰巧,默认情况下,数组实例的唯一可枚举属性是数组索引,因此通常认为它在有限的情况下执行数组索引。但事实并非如此,对此的误解咬你一口。:-) 只要您向数组添加任何其他属性(这是一件非常有效的事情),或者您正在使用的任何库决定扩展数组原型(也是一件有效的事情),它就会中断。for..in

无论如何,你得到document.getElementsByTagName 的不是一个数组这是一个NodeList。迭代 s 的最佳选择NodeList是使用明确的索引 a'la Pointy 的答案——例如,直接计数循环:

var i;
for (i = 0; i < list.length; ++i) {
    // ... do your thing ...
}

有点离题,因为它与您的 无关NodeList,但是:当您实际使用真正的数组时,由于 JavaScript 中的数组是稀疏的,因此适用于for..in,您只需要清楚自己在做什么(循环遍历属性名称,而不是索引)。您可能只想循环与数组实际条目一样多的次数,而不是循环遍历稀疏数组中间隙中的所有索引。这是你如何做到的:

var a, name;
a = [];
a[0] = "zero";
a[10000] = "ten thousand";
for (name in a) {
    // Only process this property name if it's a property of the
    // instance itself (not its prototype), and if the name survives
    // transition to and from a string unchanged -- e.g., it's numeric
    if (a.hasOwnProperty(name) && parseInt(name) == name) {
        alert(a[name]);
    }
}

以上只提示两次,“零”和“万”;而没有检查的直接计数循环会发出 10,001 次警报(主要是说“未定义”,因为它正在循环通过间隙)。

于 2010-09-06T16:43:27.783 回答
0

构造的问题for ... in是原型中的所有内容都包含在枚举中。

您的输出显示的基本上是 的每个属性images它是一个数组对象。所以你得到

  1. 数组中的所有元素,即出现在输出中的数字。
  2. 阵列上可用的所有属性。例如,这就是为什么您length在输出中看到的原因。

您的代码因数字 2 而中断,因为函数没有样式属性

所以,是的,正如 Pointy 所示,在 JavaScript 中迭代数组元素的正确方法是使用for循环。

于 2010-09-06T16:50:36.737 回答