在 JavaScript 中,将 NodeList 转换为数组的最佳方法是什么?

IT技术 javascript arrays dom
2021-03-08 17:43:06

DOM 方法document.querySelectorAll()(和其他一些方法)返回一个NodeList.

要对列表进行操作,例如 using forEach()NodeList必须首先将 转换为Array

将 the 转换NodeList为 an的最佳方法Array什么?

6个回答

使用 ES6,您可以简单地执行以下操作:

const spanList = [...document.querySelectorAll("span")];
嗨@callback,这似乎是与 TypeScript 相关的错误。您可能选择了以 es6 编译为目标,而不在 tsconfig 文件的 lib 数组中添加“es6”。问候
2021-04-24 17:43:06
@callback ES6 和 ES2015 是一回事
2021-05-01 17:43:06
请注意,您不需要将 nodeList 转换为数组以使用 forEach() - 请参阅下面的答案。
2021-05-12 17:43:06
嗨@Freezystem,你是对的!我的目标是 es2015。谢谢!
2021-05-13 17:43:06
这给了我 Type 'NodeListOf<Element>' must have a '[Symbol.iterator]()' method that returns an iterator.ts(2488)
2021-05-14 17:43:06

在 ES6 中,您可以使用Array.from(myNodeList). 然后使用您最喜欢的数组方法。

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 1
Array.from(myNodeList).forEach(function(el) {
  console.log(el);
});

使用ES6 shim也可以在较旧的浏览器中执行此操作。


如果您使用的是转译器(例如 Babel),还有两种选择:

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 2
for (var el of myNodeList) {
  el.classList.add('active'); // or some other action
}

// ALT 3
[...myNodeList].forEach((el) => {
  console.log(el);
});
所以我有这个问题,其中 Array.from(el.childNodes) 不返回第一个节点作为数组的一部分。
2021-05-10 17:43:06
@ccyoung 但迭代器在不兼容的 ES6 浏览器中不起作用,因为你不能填充 Symbol 对象,所以最好使用Array.from(myNodeList)因为它可以被填充。
2021-05-11 17:43:06
在 es6 下 nodeList 提供迭代器也不是真的吗?
2021-05-14 17:43:06

您可以使用原型中slice方法将其转换为数组Array

var elList = document.querySelectorAll('.viewcount');
elList = Array.prototype.slice.call(elList, 0);

此外,如果您只需要forEach,则可以原型中调用Array,而无需先将其强制为数组:

var elList = document.querySelectorAll('.viewcount');
Array.prototype.forEach.call(elList, function(el) {
    console.log(el);
});

在 ES6 中,您可以使用新Array.from函数将其转换为数组:

Array.from(elList).forEach(function(el) {
    console.log(el);
});

这目前仅适用于前沿浏览器,但如果您使用的是 polyfill 服务,您将可以全面访问此功能。


如果您使用的是 ES6 转译器,您甚至可以使用for..of循环:

for (var element of document.querySelectorAll('.some .elements')) {
  // use element here
}
@Daniel 这是真的,但仍然需要计算创建和销毁数组。
2021-05-01 17:43:06
谢谢。在较新的 javascript 思想/希望下有更简洁的强制。
2021-05-03 17:43:06
@JosephSilber 啊,谢谢 - 那是创建的新数组是空的[]吗?我的想法是它会被垃圾收集并且内存影响可以忽略不计,有人可以对此发表评论吗?
2021-05-12 17:43:06
@cc young - 请注意,我使用Array.prototype.forEach代替的原因[].forEach是因为后者创建了一个新的 Array 对象,这完全没有必要。
2021-05-15 17:43:06

为什么要转换?- 只是call直接在元素集合上的 Array 函数;)

[].forEach.call( $('a'), function( v, i) {
    // do something
});

当然,假设$querySelectorAll的别名


编辑:ES6 允许更短的语法[...$('a')]仅适用于 Firefox,截至 2014 年 5 月

假设$querySelectorAll
2021-04-26 17:43:06
如果您打算使用 jQuery,那么更简洁的解决方案是: $('a').each(function(i, v) {...});
2021-04-26 17:43:06
题外话EcmaScript 5 已经是一年的标准了,所有当前的浏览器都支持 Arrays 的新方法,问题具体是关于在 NodeList aka Element collection 上使用这些方法。
2021-04-27 17:43:06
哈哈哈,为什么 ?没有什么可以禁止您创建像function $ ( s ) { return document.querySelectorAll(s); }.
2021-05-06 17:43:06
您的回答暗示了 jQuery 的使用。如果是这样的话,这种愚蠢的做法是完全没有必要的,感谢.each().
2021-05-20 17:43:06

2020 年更新:nodeList.forEach() 现在是官方标准,并在所有当前浏览器中受支持。

较旧的浏览器可以使用下面的 polyfill。

要在javascript 中对列表进行操作,例如使用forEach(),必须将NodeList 转换为数组。

这不是真的。.forEach()适用于当前浏览器。如果它丢失,您可以使用 polyfill 将 .forEach() 从Array添加NodeList并且它工作正常:

if ( ! NodeList.prototype.forEach ) {
  NodeList.prototype.forEach = Array.prototype.forEach;
}

您现在可以运行:

myNodeList.forEach(function(node){...})

像数组一样遍历 NodeList。

这会产生比 .call() 任何地方都更短、更干净的代码。

@DuBistKomisch 这是一个 polyfill,仅在标准 NodeList.foreach() 不存在时应用。
2021-04-26 17:43:06
这个答案正是我所需要的,这 3 行代码节省了大量时间。所有其他答案都需要更改一堆代码,我不明白为什么。
2021-05-07 17:43:06
啊我的错,没有意识到他们实际上是forEach专门添加的,我来这里是为了寻找filter
2021-05-13 17:43:06
@DuBistKomisch 您可以对 使用相同的技术filter,但NodeList.prototype.dbkFilter如果您担心使用不同实现的未来标准,您可能希望给它一个非官方名称或类似名称
2021-05-15 17:43:06
否决票可能是因为猴子修补内置原型被认为是不好的做法
2021-05-16 17:43:06