![](/img/trans.png)
[英]In JavaScript, what is the best way to convert a NodeList to an array?
[英]Fastest way to convert JavaScript NodeList to Array?
之前在这里回答的问题说这是最快的方法:
//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);
他们都生产相同的 output,但我很难相信我的第二个版本是最快的方法,特别是因为人们在这里说了其他话。
这是我的浏览器(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++]));
EDIT2:我找到了一种更快的方法
// nl is the nodelist
var arr = [];
for(var i = nl.length; i--; arr.unshift(nl[i]));
使用 ES6,我们现在有一种从 NodeList 创建数组的简单方法: Array.from()
函数。
// nl is a NodeList
let myArray = Array.from(nl)
所以你可以简单地做:
document.querySelectorAll('img').forEach(highlight);
其他案例
如果您出于某种原因想要将其转换为数组,而不仅仅是迭代它 - 这是一个完全相关的用例 - 您可以使用[...destructuring]
或Array.from
从 ES6
let array1 = [...mySetOfElements];
// or
let array2 = Array.from(mySetOfElements);
这也适用于不是 NodeLists 的其他类似数组的结构
document.getElementsByTagName
返回的HTMLCollection
Map
和Set
等对象)过时的 2010 年答案
在某些浏览器中,第二个往往更快,但重点是您必须使用它,因为第一个不是跨浏览器。 即使时代变了
@kangax ( IE 9 预览版)
Array.prototype.slice现在可以将某些宿主对象(例如 NodeList's)转换为数组——大多数现代浏览器已经能够做到这一点已经有一段时间了。
例子:
Array.prototype.slice.call(document.childNodes);
这是使用ES6 扩展运算符的一种新的很酷的方法:
let arr = [...nl];
在 ES6 中,您可以使用:
数组.from
let array = Array.from(nodelist)
扩展运算符
let array = [...nodelist]
一些优化:
代码( jsPerf ):
var arr = [];
for (var i = 0, ref = arr.length = nl.length; i < ref; i++) {
arr[i] = nl[i];
}
最快和跨浏览器是
for(var i=-1,l=nl.length;++i!==l;arr[i]=nl[i]);
正如我比较
http://jsbin.com/oqeda/98/edit
*感谢@CMS 的想法!
假设nodeList = document.querySelectorAll("div")
,这是将nodelist
转换为数组的简洁形式。
var nodeArray = [].slice.call(nodeList);
看我在这里使用它。
NodeList.prototype.forEach = Array.prototype.forEach;
现在你可以做 document.querySelectorAll('div').forEach(function()...)
更快更短:
// nl is the nodelist
var a=[], l=nl.length>>>0;
for( ; l--; a[l]=nl[l] );
这是我在 JS 中使用的函数:
function toArray(nl) {
for(var a=[], l=nl.length; l--; a[l]=nl[l]);
return a;
}
在这里查看这篇博客文章,讨论同样的事情。 据我所知,额外的时间可能与沿着作用域链向上走有关。
以下是截至本文发布之日更新的图表(“未知平台”图表是 Internet Explorer 11.15.16299.0):
从这些结果来看,似乎 preallocate 1 方法是最安全的跨浏览器赌注。
这里有一个衬垫,我不确定它是否安全,但它对我有用,它用数组覆盖 nodelist 变量,因为我不再使用 nodelist,因为我将它转换为数组。 我发现这个解决方案更干净,因为它只使用一个变量。
this.openButtons = [...this.openButtons]
最简单的方法:
Array.from(document.querySelectorAll('.back-top'))
就去做吧 vat arr = [...nodeList]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.