Javascript 为什么节点列表包含未在其长度属性中反映的额外未定义项? 背景:
在处理节点列表时,我遇到了一个非常奇怪的现象。我想使用getElementsByClassName或类似的东西,然后对它进行排序。我决定一种方法是迭代节点列表,将每个项推送到一个数组中,并对数组进行排序。(顺便说一句,这确实有效,但没有达到预期效果)。我尝试使用Javascript 为什么节点列表包含未在其长度属性中反映的额外未定义项? 背景:,javascript,for-loop,nodelist,Javascript,For Loop,Nodelist,在处理节点列表时,我遇到了一个非常奇怪的现象。我想使用getElementsByClassName或类似的东西,然后对它进行排序。我决定一种方法是迭代节点列表,将每个项推送到一个数组中,并对数组进行排序。(顺便说一句,这确实有效,但没有达到预期效果)。我尝试使用for(nodeList中的var I)进行迭代,但它一直在最后几个未定义的项上抛出异常。奇怪的是,我可以使用for(var I=0;I
for(nodeList中的var I)
进行迭代,但它一直在最后几个未定义的项上抛出异常。奇怪的是,我可以使用for(var I=0;I
进行迭代。我刚刚再次测试了它,并在控制台的stackoverflow页面上运行了以下代码:
for (var i in document.getElementsByTagName("span"))
console.count("items");
console.log(document.getElementsByTagName("span").length);
它算出了项:382项,但长度为380项。正如所料,当我输入document.getElementsByTagName(“span”)[380]
和document.getElementsByTagName(“span”)[381]
时,它们返回时没有定义。这种奇怪的行为不会发生在数组上(当然,节点列表和数组是不同的,但这确实证明了引起问题的循环并不是不同的)
问题:
为什么for(nodeList中的var i)
构造在最后返回两个未定义项的nodeList上的行为不同?迭代语句中的for捕获的两个附加属性是:
- 长度
- 项目
让我给你举个简单的例子。假设页面上有3个SPAN元素
var spans = document.getElementsByTagName( 'span' );
现在,span
是一个节点列表对象,它包含5属性:
- 0
- 一,
- 二,
- 长度
- 项目
前3个属性是索引,它们包含对这些跨度元素的引用。其他两个属性-长度和项目-是两个附加属性。所有节点列表对象都具有这两个属性
for in
语句迭代NodeList对象的所有5个属性,这可能不是您想要的。因此,使用常规的for
语句
var i, span;
for ( i = 0; i < spans.length; i++ ) {
span = spans[i];
// do stuff with span
}
vari,span;
对于(i=0;i
for in迭代对象的所有可枚举属性,例如长度和项目(这是您的情况)。这是另外两个结果的来源。它还将枚举添加到对象原型中的所有内容
for循环遍历数值索引,不考虑可枚举属性。这就是为什么使用前一种方法更可靠。节点列表对象类似于数组。因此,不要在
中使用
进行迭代,而是在
中使用进行迭代。顺便说一句,您可以将节点列表对象转换为规则数组,如下所示:[].slice.call(NodeList)
。谢谢@Šime Vidas,但为什么会出现这种情况?是什么导致了这种奇怪的行为?for in
对对象不起作用吗?我在回答中做了解释……再次感谢你,西姆·维达斯。现在这完全有道理了这是有道理的。非常感谢你的解释。现在我知道了,下次再说吧另外,感谢您提供了如何将节点列表转换为数组的代码片段。“这将在未来非常有用。”约瑟夫注意到,尽管我认为这种黑客在IE8中不起作用。我碰巧不在乎IE8,所以我的答案和建议应该一直小心地执行。:)
lol无论如何我都很感激。XD我一直在寻找这样的小技巧。谢谢你的回答和简洁的定义。