is one of the most glaring issues. And of all those array-like objects,
NodeLists are one of the most commonly used ones array-like objects that
beginners trip on when they use methods like
So what is exactly an NodeList? The W3C defines the NodeList as follows:
The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented.
Essentially, a NodeList is what you get when you call any method such as
document.querySelectorAll() and such.
Definitely looks like an array from here, if nothing else other than fact that
the way our console inspects
myList starts and ends with a square bracket.
Let’s try some basic array actions with it:
myList has been talking and walking like an array so we can probably
assume that it’s an array of some sorts. However, it all goes to hell when you
try to call any of the basic array methods. Suppose we want to slice the array
from it’s 3rd element.
Let’s see what an array, that we definitely know to be an array looks like using the same technique (where we look at its’ constructor).
So those two elements,
surelyArray are definitely constructed
by different constructors so it’s no wonder that they don’t share the same
In fact, it turns out that NodeLists support accessing elements by their index
and they do have
length property but that’s essentially where the
similarities end. If you want to call any of the array methods on a NodeList,
you will just get an error.
Let’s think about why this is the case. If you think about what NodeLists are
and the re-read the definition, this (kind of) makes sense. While arrays are
essentially a collection of elements held in memory and are part of the
document.querySelectorAll() method, which returns not live but static
Luckily, you can relatively easily convert NodeLists into arrays so that you
can easily call all your favorite array methods like
Let’s see a quick way to convert a NodeList into an array:
Definitely looks like an array! Before we look at what happened with that
one-liner, let’s really make sure that this
myArray is an actual array, not
some other crazy creation.
Not bad. We are definitely sure that we are dealing with an array here.
The one-liner we used before is actually pretty simple. What we are
essentially doing here is borrowing the
slice() method from the Array’s
prototype and applying it to on NodeList, slicing it from it’s beginning, so
getting the entire list itself. And as
slice() returns an actual array, we
end with a real array, as opposed to a NodeList. More explanation on
works can be found on Robert Sosinski’s excellent post on Binding Scope in
There you have it. Except, if you use Internet Explorer. It turns out that
Internet Explorer versions before Internet Explorer 9 cannot handle calling
slice() on NodeLists –and in general behave badly on host object
One way to fix that problem is simple create a new array, iterate over your existing NodeList and push things into your new array.
This is a good start but however there’s a slight issue with that code that
James-David Dalton pointed out. It’s possible
for a NodeList to have an element in it that has the id
length. In that
case, the expression
myList.length would no longer be an integer but the
element with the id
length itself. Nevertheless, this is easy to fix.
This code involves a bit more trickery. In essence, we are again looping over
the elements in the
myList NodeList but making sure that a given index is
i to -1 is that we increment the index before we actually
try to access the
ith index. So if we were to set the
i to 0 instead of
-1, we would both miss the first element in the MyList NodeList and also start
setting the elements in the
myIEArray from its 1st index, leaving
There you have it, for real this time, a real array from your NodeList.
One thing is worth mentioning though; when you convert your NodeList into an
array, you are no longer dealing with a live NodeList (again,
document.querySelectorAll() actually returns not live but static NodeLists)
but instead an array of DOM nodes.
Converting a NodeList into an array has some interesting consequences. Going
back to our example where we ran the
myArray.pop(), you’d not the top Digg
story disappearing as your array is just a collection of DOM nodes, not
representation of your DOM anymore.
However, the DOM objects themselves are live. So if you were to do something
myArray.innerHTML('foo bar'), you would instead change the DOM.
NodeLists are a powerful tool and with more and more browsers getting decent DOM APIs, you might find yourself dealing with more NodeLists instead of jQuery objects and such.
In fact, if you look at the source code for Thomas Fuchs’ Zepto.JS
micro-library, you’ll find that it implements arguably the most important
aspect of jQuery, the CSS DOM selector using the (relatively) new
document.querySelectorAll() method and converting the NodeList to an array
for easy further manipulation.
I hope this brief introduction to NodeLists (and arrays) has been useful. Please let me know in the comments if you have any questions or corrections.