In JavaScript, what is the best way to convert a NodeList to an array?

The DOM method document.querySelectorAll() (and a few others) return a NodeList.

To operate on the list, e.g. using forEach(), the NodeList must first be converted to an Array.

What's the best way to convert the NodeList to an Array?


Solution 1:

With ES6 you can simply do:

const spanList = [...document.querySelectorAll("span")];

Solution 2:

With ES6 you can use Array.from(myNodeList). Then use your favourite array method.

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 1
Array.from(myNodeList).forEach(function(el) {
  console.log(el);
});

Use an ES6 shim to make this work in older browsers too.


If you are using a transpiler (for example Babel) there are two more alternatives:

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 2
for (var el of myNodeList) {
  el.classList.add('active'); // or some other action
}

// ALT 3
[...myNodeList].forEach((el) => {
  console.log(el);
});

Solution 3:

You can convert it to an array by using the slice method from the Array prototype:

var elList = document.querySelectorAll('.viewcount');
elList = Array.prototype.slice.call(elList, 0);

Furthermore, if all you need is forEach, you can invoke that from the Array prototype, without coercing it to an array first:

var elList = document.querySelectorAll('.viewcount');
Array.prototype.forEach.call(elList, function(el) {
    console.log(el);
});

In ES6, you can use the new Array.from function to convert it to an array:

Array.from(elList).forEach(function(el) {
    console.log(el);
});

This is currently only in bleeding edge browsers, but if you're using a polyfill service you will have access to this function across the board.


If you're using an ES6 transpiler, you can even use a for..of loop instead:

for (var element of document.querySelectorAll('.some .elements')) {
  // use element here
}

Solution 4:

Why convert? - just call function of Array directly on element collection ;)

[].forEach.call( $('a'), function( v, i) {
    // do something
});

assuming $ is your alias for querySelectorAll, of course


edit: ES6 allows for even shorter syntax [...$('a')] (works in Firefox only, as of May 2014)