我偶尔会因无法将DOM元素集合(更正式地称为NodeList
)像数组一样进行操作而感到NodeList
,因为它不是一个数组。 但是,它确实看起来像一个,并且认为这是JavaScript新手经常犯的一个错误,以至于我们即将发布的JavaScript参考中,我认为有必要针对作为集合或返回集合的每个 DOM对象注意这一点。
您可以遍历像数组这样的集合:
for(var i=0; i<collection.length; i++)
{
//whatever
}
但是您不能使用诸如push()
, splice()
或reverse()
类的Array
方法来对其进行操作。
除非您可以进行下一步,然后将其转换为array ,否则可以。 这实际上是微不足道的:
function collectionToArray(collection)
{
var ary = [];
for(var i=0, len = collection.length; i < len; i++)
{
ary.push(collection[i]);
}
return ary;
}
上面的代码是完全跨浏览器的,并以原始集合作为参数调用:
var elements = collectionToArray(document.getElementsByTagName('*'));
但是,如果只需要处理支持本机对象原型的浏览器(Opera,Firefox和Safari 3),则可以简单地创建NodeList
的toArray()
方法:
NodeList.prototype.toArray = function()
{
var ary = [];
for(var i=0, len = this.length; i < len; i++)
{
ary.push(this[i]);
}
return ary;
};
然后可以将其称为单个集合的方法:
var elements = document.getElementsByTagName('*').toArray();
这种转换(无论如何完成)有一个明显的缺点,那就是结果数组将不再是NodeList
。 很明显,是的,但是很重要,因为它有两个含义:
- 它将失去它从
NodeList
继承的属性和方法 。 但是,NodeList
仅具有一个属性(它的length
,它也可用于数组)和一个方法(item()
方法,无论如何通常都是多余的,因为仍然可以使用方括号表示法来引用成员)。 因此,这种损失一点也不重要 - 它将不再是实时收集 。
NodeList
是对对象集合的引用 ,如果该集合发生更改(例如,添加或删除了元素),则NodeList
将自动更新以反映该更改。 相反,我们的数组是某个时间点集合的静态快照,因此不会响应DOM中的更改而更新。 根据您的应用程序,这可能很重要。
From: https://www.sitepoint.com/a-collection-is-not-an-array/