我正在进行一项任务,该任务涉及使用for
循环使用以下代码迭代HTML页面上所有按钮标记的NodeList:
var bns = document.getElementsByTagName("button");
for (var i = 0; i < bns.length; i++) {
bns[i].addEventListener("click", function() {
alert("you clicked");
});
}
但是,这段代码很有用,我很难理解为什么有必要这样做,即将NodeList放入数组中以便访问它。 NodeList已经是一个数组吗?
答案 0 :(得分:5)
nodeList是一个类似于数组的对象。它实际上不是一个数组。 ONLY属性的共同点是数组.length
和数组索引。它没有任何其他数组方法。
但是,因为它支持数组索引和.length
属性,所以您可以使用for
循环迭代它,就像使用数组一样。但是,您不能在其上使用.forEach()
,因为这是nodeList
对象没有的实际数组方法。
您问题中的代码根本不是“将nodeList放入数组中”。它使用nodeList
和.length
访问bns[i]
对象的元素以访问nodeList的数字属性。
您可以将nodeList对象想象得更像:
var myNodeList = {
length: 3,
"0": domObj1,
"1": domObj2,
"2": domObj3
};
在这个类似数组的对象中,你可以这样做:
for (var i = 0; i < myNodeList.length; i++) {
console.log(myNodeList[i]);
}
即使它实际上不是一个数组。 nodeList
实际上是一种主机对象形式,它被赋予了有限的Javascript接口。
仅供参考,有时将nodeList复制到实际数组中 - 当您想要将动态nodeList创建为静态数组时,或者希望能够在其上使用更多Array方法时。这可以这样做:
var bns = document.getElementsByTagName("button");
// copy the nodeList into an actual array
var myArray = Array.prototype.slice.call(bns);
myArray.forEach(function(item) {
console.log(item);
});
仅供参考,这是MDN关于Why is nodeList not an Array的一个很好的部分。
而且,Array.prototype.slice.call(nodeList)
转换需要IE9 +。如果您希望在旧版本的IE中支持,则可以使用垫片here。