Let's suppose we want to select all the li
elements from the following list:
<ul id="list"> <li>foo</li> <li>bar</li> <li>baz</li> </ul>
If we were to use querySelectorAll()
for selecting all the li
elements in the list above, we would get a NodeList
object, for example:
const listItems = document.querySelectorAll('li'); console.log(listItems); // output: NodeList(3) [li, li, li]
What Is a NodeList
Object?
A DOM NodeList
object is not an array, but an "array-like" object that consists of an iterable collection of nodes. In JavaScript, an object is array-like when it:
- Has indexed access to elements (e.g.
listItems[0]
); - Has the
length
property which can tell us how many elements the object has (e.g.listItems.length
); - Does NOT have array methods such as
push
,forEach
,indexOf
, etc. because the object is not constructed usingArray
or[]
. This means it does not inherit array properties/methods fromArray.prototype
.
So as you can see, some of the array methods won't work on a NodeList
. To work around this, we can simply convert the NodeList
object to an array using any of the methods explained in this article.
Convert NodeList
to Array Using Array.from()
Array.from()
creates a new, shallow-copied Array
instance from an array-like or iterable object. Since a NodeList
is both, iterable and "array-like", we can use Array.from()
to convert a NodeList
to an array like so:
// ES6+ const listItems = document.querySelectorAll('li'); const list = Array.from(listItems); console.log(list); // output: (3) [li, li, li]
The use of Array.from()
is not just limited to NodeList
objects; it works on any object that is either:
- Iterable (such as
Map
,Set
, etc.), or; - Array-like object (such as DOM
NodeList
, etc.).
Convert NodeList
to Array Using the Spread Operator
The spread operator can be used to make an array out of a NodeList
object like so:
// ES6+ const listItems = document.querySelectorAll('li'); const list = [ ...listItems ]; console.log(list); // output: (3) [li, li, li]
It is important to note that converting an object to an array using the spread operator only works on objects that are iterable.
Convert NodeList
to Array Using a for
Loop
Since a NodeList
object is an indexed iterable collection, we can simply iterate over its elements and copy them into a new array like so:
const listItems = document.querySelectorAll('li'); const list = []; for (let i = 0; i < listItems.length; i++) { list[i] = listItems[i]; } console.log(list); // output: (3) [li, li, li]
The for
loop can also be shortened to a one-liner like so:
for (let i = 0; i < listItems.length; list[i] = listItems[i], i++);
The advantage of using a for
loop for converting a NodeList
to an array is browser compatibility and possibly speed.
Convert NodeList
to Array Using Array.prototype.slice()
Calling slice()
in the following way returns a new array with all the nodes copied over from the NodeList
collection:
const listItems = document.querySelectorAll('li'); const list = Array.prototype.slice.call(listItems); console.log(list); // output: (3) [li, li, li]
This can be shortened to:
const list = [].slice.call(listItems);
This method is considered a bit hacky, however, it does have good browser support.
This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.