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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3199588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:38:47  来源:igfitidea点击:

Fastest way to convert JavaScript NodeList to Array?

javascriptarraysnodelist

提问by jairajs89

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.

它们都产生相同的输出,但我发现很难相信我的第二个版本是最快的方式,尤其是因为人们在这里另有说法。

Is this a quirk in my browser (Chromium 6)? Or is there a faster way?

这是我的浏览器(Chromium 6)中的一个怪癖吗?或者有没有更快的方法?

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]));

采纳答案by gblazex

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)

@kangaxIE 9 预览版

Array.prototype.slicecan now convert certain host objects (e.g. NodeList's) to arrays — something that majority of modern browsers have been able to do for quite a while.

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

Example:

例子:

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

回答by webdif

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)

回答by Alexander Olsson

Here's a new cool way to do it using the ES6 spread operator:

这是使用ES6 扩展运算符的一种新的很酷的方法:

let arr = [...nl];

回答by Thai

Some optimizations:

一些优化:

  • save the NodeList's length in a variable
  • explicitly set the new array's length before setting.
  • access the indices, rather than pushing or unshifting.
  • 将 NodeList 的长度保存在一个变量中
  • 在设置之前显式设置新数组的长度。
  • 访问索引,而不是推送或取消移动。

Code (jsPerf):

代码(jsPerf):

var arr = [];
for (var i = 0, ref = arr.length = nl.length; i < ref; i++) {
 arr[i] = nl[i];
}

回答by 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:

回答by Felipe Buccioni

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 的想法!

Chromium (Similar to Google Chrome)FirefoxOpera

Chromium(类似于 Google Chrome)火狐歌剧

回答by Isabella

In ES6 you can either use:

在 ES6 中,您可以使用:

  • Array.from

    let array = Array.from(nodelist)

  • Spread operator

    let array = [...nodelist]

  • 数组.from

    let array = Array.from(nodelist)

  • 展开运算符

    let array = [...nodelist]

回答by John Williams

NodeList.prototype.forEach = Array.prototype.forEach;

Now you can do document.querySelectorAll('div').forEach(function()...)

现在你可以做 document.querySelectorAll('div').forEach(function()...)

回答by anonymous

faster and shorter :

更快更短:

// nl is the nodelist
var a=[], l=nl.length>>>0;
for( ; l--; a[l]=nl[l] );

回答by Vivin Paliath

Check out this blog post herethat talks about the same thing. From what I gather, the extra time might have to do with walking up the scope chain.

在这里查看这篇博客文章它讨论了同样的事情。从我收集的信息来看,额外的时间可能与沿作用域链向上走有关。