将JavaScript NodeList转换为数组的最快方法?

2022-08-29 23:50:50

这里之前回答过的问题说,这是最快的方法:

//nl is a NodeList
var arr = Array.prototype.slice.call(nl);

在我的浏览器上进行基准测试时,我发现它比这慢3倍以上:

var arr = [];
for(var i = 0, n; n = nl[i]; ++i) arr.push(n);

它们都产生相同的输出,但我发现很难相信我的第二个版本是最快的方法,特别是因为人们在这里说了不同的话。

这是我的浏览器(Chromium 6)中的怪癖吗?还是有更快的方法?

编辑:对于任何关心的人,我确定了以下内容(这似乎是我测试的每个浏览器中最快的):

//nl is a NodeList
var l = []; // Will hold the array of Node's
for(var i = 0, ll = nl.length; i != ll; l.push(nl[i++]));

编辑2:我找到了一种更快的方法

// nl is the nodelist
var arr = [];
for(var i = nl.length; i--; arr.unshift(nl[i]));

答案 1

使用ES6,我们现在有一个简单的方法从NodeList创建数组:Array.from()函数。

// nl is a NodeList
let myArray = Array.from(nl)

答案 2

2021年更新:nodeList.forEach()现在是标准配置,并且支持所有当前的浏览器(在桌面和移动设备上都支持约95%)

因此,您只需执行以下操作:

document.querySelectorAll('img').forEach(highlight);

其他案例

如果您出于某种原因想要将其转换为数组,而不仅仅是迭代它 - 这是一个完全相关的用例 - 您可以使用[...destructuring]Array.from 自 ES6

let array1 = [...mySetOfElements];
// or
let array2 = Array.from(mySetOfElements);

这也适用于其他不是 NodeList 的类似数组的结构

  • HTMLCollection返回者例如document.getElementsByTagName
  • 具有长度属性和索引元素的对象
  • 可迭代对象(对象,如 和MapSet)



过时的2010年答案

第二个在某些浏览器中往往更快,但重点是你必须使用它,因为第一个不是跨浏览器的。即使时代他们正在改变

@kangaxIE 9 预览版))

Array.prototype.slice现在可以将某些主机对象(例如NodeList的)转换为数组 - 这是大多数现代浏览器已经能够做到很长一段时间的事情。

例:

Array.prototype.slice.call(document.childNodes);