[英]Fastest way to convert JavaScript NodeList to Array?
Previously answered questions here said that this was the fastest way:之前在这里回答的问题说这是最快的方法:
//nl is a NodeList
var arr = Array.prototype.slice.call(nl);
In benchmarking on my browser I have found that it is more than 3 times slower than this:在我的浏览器上进行基准测试时,我发现它比这慢了 3 倍以上:
var arr = [];
for(var i = 0, n; n = nl[i]; ++i) arr.push(n);
They both produce the same output, but I find it hard to believe that my second version is the fastest possible way, especially since people have said otherwise here.他们都生产相同的 output,但我很难相信我的第二个版本是最快的方法,特别是因为人们在这里说了其他话。
Is this a quirk in my browser (Chromium 6)?这是我的浏览器(Chromium 6)中的一个怪癖吗? Or is there a faster way?
还是有更快的方法?
EDIT: For anyone who cares, I settled on the following (which seems to be the fastest in every browser that I tested):编辑:对于任何关心的人,我选择了以下内容(这似乎是我测试的每个浏览器中最快的):
//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: I found an even faster way EDIT2:我找到了一种更快的方法
// nl is the nodelist
var arr = [];
for(var i = nl.length; i--; arr.unshift(nl[i]));
With ES6, we now have a simple way to create an Array from a NodeList: the Array.from()
function.使用 ES6,我们现在有一种从 NodeList 创建数组的简单方法:
Array.from()
函数。
// nl is a NodeList
let myArray = Array.from(nl)
So you can simply do:所以你可以简单地做:
document.querySelectorAll('img').forEach(highlight);
Other cases其他案例
If you for some reason want to convert it to an array, not just iterate over it - which is a completely relevant use-case - you can use [...destructuring]
or Array.from
since ES6如果您出于某种原因想要将其转换为数组,而不仅仅是迭代它 - 这是一个完全相关的用例 - 您可以使用
[...destructuring]
或Array.from
从 ES6
let array1 = [...mySetOfElements];
// or
let array2 = Array.from(mySetOfElements);
This also works for other array-like structures that aren't NodeLists这也适用于不是 NodeLists 的其他类似数组的结构
HTMLCollection
returned by eg document.getElementsByTagName
document.getElementsByTagName
返回的HTMLCollection
Map
and Set
)Map
和Set
等对象) Outdated 2010 Answer过时的 2010 年答案
The second one tends to be faster in some browsers, but the main point is that you have to use it because the first one is just not cross-browser.在某些浏览器中,第二个往往更快,但重点是您必须使用它,因为第一个不是跨浏览器。 Even though The Times They Are a-Changin'
即使时代变了
@kangax ( IE 9 preview ) @kangax ( IE 9 预览版)
Array.prototype.slice can now convert certain host objects (eg NodeList's) to arrays — something that majority of modern browsers have been able to do for quite a while.
Array.prototype.slice现在可以将某些宿主对象(例如 NodeList's)转换为数组——大多数现代浏览器已经能够做到这一点已经有一段时间了。
Example:例子:
Array.prototype.slice.call(document.childNodes);
这是使用ES6 扩展运算符的一种新的很酷的方法:
let arr = [...nl];
In ES6 you can either use:在 ES6 中,您可以使用:
Array.from数组.from
let array = Array.from(nodelist)
Spread operator扩展运算符
let array = [...nodelist]
Some optimizations:一些优化:
var arr = [];
for (var i = 0, ref = arr.length = nl.length; i < ref; i++) {
arr[i] = nl[i];
}
The most fast and cross browser is最快和跨浏览器是
for(var i=-1,l=nl.length;++i!==l;arr[i]=nl[i]);
As I compared in正如我比较
http://jsbin.com/oqeda/98/edit http://jsbin.com/oqeda/98/edit
*Thanks @CMS for the idea! *感谢@CMS 的想法!
The results will completely depend on the browser, to give an objective verdict, we have to make some performance tests, here are some results, you can run them here :结果将完全取决于浏览器,为了给出客观的判断,我们必须进行一些性能测试,这里有一些结果,你可以在这里运行它们:
Chrome 6:铬 6:
Firefox 3.6:火狐 3.6:
Firefox 4.0b2:火狐 4.0b2:
Safari 5:野生动物园 5:
IE9 Platform Preview 3: IE9 平台预览版 3:
NodeList.prototype.forEach = Array.prototype.forEach;
现在你可以做 document.querySelectorAll('div').forEach(function()...)
faster and shorter :更快更短:
// nl is the nodelist
var a=[], l=nl.length>>>0;
for( ; l--; a[l]=nl[l] );
This is the function I use in my JS:这是我在 JS 中使用的函数:
function toArray(nl) {
for(var a=[], l=nl.length; l--; a[l]=nl[l]);
return a;
}
Here are charts updated as of the date of this posting ("unknown platform" chart is Internet Explorer 11.15.16299.0):以下是截至本文发布之日更新的图表(“未知平台”图表是 Internet Explorer 11.15.16299.0):
From these results, it seems that the preallocate 1 method is the safest cross-browser bet.从这些结果来看,似乎 preallocate 1 方法是最安全的跨浏览器赌注。
One liner here, I am not sure if it is safe, but it works for me, it is overwriting the nodelist variable with an array, because I no longer use the nodelist, as I converted it to an array.这里有一个衬垫,我不确定它是否安全,但它对我有用,它用数组覆盖 nodelist 变量,因为我不再使用 nodelist,因为我将它转换为数组。 I find this solution cleaner as it uses just the one variable.
我发现这个解决方案更干净,因为它只使用一个变量。
this.openButtons = [...this.openButtons]
最简单的方法:
Array.from(document.querySelectorAll('.back-top'))
就去做吧 vat arr = [...nodeList]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.