Fastest way to convert JavaScript NodeList to Array?

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:
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?
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
// nl is the nodelist
var arr = [];
for(var i = nl.length; i–; arr.unshift(nl[i]));

Solutions/Answers:

Solution 1:

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’

Related:  How to reload page every 5 seconds?

@kangax (IE 9 preview)

Array.prototype.slice can 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.

Example:

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

Solution 2:

With ES6, we now have a simple way to create an Array from a NodeList: the Array.from() function.

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

Solution 3:

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

let arr = [...nl];

Solution 4:

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.

Code (jsPerf):

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

Solution 5:

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:

Firefox 3.6:

Firefox 4.0b2:

Related:  ESLint with React gives `no-unused-vars` errors

Safari 5:

IE9 Platform Preview 3:

Solution 6:

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

*Thanks @CMS for the idea!

Chromium (Similar to Google Chrome)
Firefox
Opera