在Javascript中进行for-in迭代

时间:2013-10-30 23:24:32

标签: javascript

代码:

<!DOCTYPE html>
<html>
<body>
<p>This.........</p>
<p>That.....</p>
<p>And yet .....</p>
<script>
x=document.getElementsByTagName("p");
for (i in x)  
    document.write("..."+x[i].innerHTML+" "+i+"<br>");
document.write(x.length);
</script>
</body>
</html>

我正在获得输出

This.........

That.....

And yet .....
...This......... 0
...That..... 1
...And yet ..... 2
...undefined item
...undefined namedItem
...undefined iterator
...undefined length
3

而不是以下是我所期望的:

This.........

That.....

And yet .....
...This......... 0
...That..... 1
...And yet ..... 2
3
for-in 语句应该在 x 上迭代 x 的长度 - 这是 3代码本身正在说 - 并终止。它似乎正在做的是迭代 在节点的所有子节点上 - 而不仅仅是段落标记 由 document.getElementsByTagName(“p”)返回。

这是我在代码中遗漏的一些细微之处,或者是JavaScript引擎中的错误。

这里缺少什么?

2 个答案:

答案 0 :(得分:7)

不要将for ... in用于数组和类似数组的事物,如NodeList对象。始终使用数字索引。

for ... in构造用于迭代对象的可枚举属性。严格来说,它甚至不能保证数字属性将以数字顺序遍历!使用数字索引,或者将类似数组的对象转换为实数数组并使用.forEach()(在较新的浏览器中):

var x = document.getElementsByTagName("p");
[].slice.call(x, 0).forEach(function(value, index) {
  document.write("..." + value.innerHTML + " " + index + "<br>");
});

编辑 - RobG正确指出.slice()技巧在IE9之前的IE版本中不起作用。使用带有数字索引的简单for循环来做同样的事情很容易,所以如果您担心IE8或更低版本,请执行以下操作:

var x = document.getElementsByTagName("p");
for (var i = 0; i < x.length; ++i) {
  // whatever with x[i]
}

我认为,真正旧版本的Mozilla甚至不支持对Node对象使用数组索引;你必须使用.item( i )方法。但我不认为这是对现实新代码的严重关注。

答案 1 :(得分:1)

var x=document.getElementsByTagName("p");
for(var i=0;i<x.length;i++)
{
  document.write("..."+x[i].innerHTML+" "+i+"<br>");
}