Javascript for ... in语句在循环数组时给出错误

时间:2010-09-06 16:34:15

标签: javascript arrays getelementsbytagname

我刚试过Javascript中的for...in语句。

这没有错误:

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循环更好?

3 个答案:

答案 0 :(得分:5)

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

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

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

(实际上从getElementsByTagName回来的不是真的一个数组;它是一个节点列表。但是你可以像对待数组那样对待它,它通常都可以正常工作。同样基本的警告适用于for ... in。)

答案 1 :(得分:1)

for..in不循环遍历数组的索引,它遍历对象的可枚举属性名称。碰巧的是,默认情况下,唯一可枚举的属性数组实例是数组索引,因此它主要认为它在有限的情况下执行数组索引。但这不是for..in所做的,误解这个咬你。 :-)一旦你向数组添加任何进一步的属性(一个完全有效的事情)或你正在使用的任何库决定扩展数组原型(也是一个有效的事情)它会中断。

在任何情况下,您从document.getElementsByTagName 返回的内容都不是数组It's a NodeList。迭代NodeList s的最佳选择是使用显式索引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次(大多数说“未定义”,因为它在循环中循环)。

答案 2 :(得分:0)

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

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

  1. 数组中的所有元素,即输出中显示的数字。
  2. 阵列上可用的所有属性。这就是您在输出中看到length的原因。
  3. 您的代码由于数字2而中断,因为函数没有样式属性

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