代码:
<!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引擎中的错误。
这里缺少什么?
答案 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>");
}