我刚试过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
循环更好?
答案 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
的每个属性,它是一个数组对象。所以你得到了
length
的原因。您的代码由于数字2而中断,因为函数没有样式属性
所以,是的,as Pointy shows,在JavaScript中迭代数组元素的正确方法是使用for
循环。