在Javascript中进行for-in迭代

ash*_*ley 0 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>
Run Code Online (Sandbox Code Playgroud)

我得到了输出

This.........

That.....

And yet .....
...This......... 0
...That..... 1
...And yet ..... 2
...undefined item
...undefined namedItem
...undefined iterator
...undefined length
3
Run Code Online (Sandbox Code Playgroud)

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

This.........

That.....

And yet .....
...This......... 0
...That..... 1
...And yet ..... 2
3
Run Code Online (Sandbox Code Playgroud)

换的语句应该在迭代X多次的长度X -这是3作为代码本身saying--并终止.它似乎正在做的是迭代节点的所有子节点 - 而不仅仅是document.getElementsByTagName("p")返回的段落标记.

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

这里缺少什么?

Poi*_*nty 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>");
});
Run Code Online (Sandbox Code Playgroud)

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

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

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