In the documentation, it says that :
[the returned list of elements] is a non-live NodeList
of element objects.
NodeList
is different from an array (entirely-different prototype-chain) and the documentation also tells you why you cannot use forEach
:
Why can't I use forEach
or map
on a NodeList
?
NodeList
are used very much like arrays and it would be tempting to use Array.prototype
methods on them, however they don't have those methods.
JavaScript has an inheritance mechanism based on prototypes for both built–in objects (like Array
s) and host objects (like NodeList
s). Array
instances inherit array methods (such as forEach
or map
) because their prototype chain looks like the following:
myArray --> Array.prototype --> Object.prototype --> null
(The prototype chain of an object can be obtained by calling Object.getPrototypeOf several times.)
forEach
, map
and the likes are own properties of the Array.prototype
object.
Unlike arrays, NodeList
prototype chain looks like the following:
myNodeList --> NodeList.prototype --> Object.prototype --> null
NodeList.prototype
contains the item method, but none of the Array.prototype
methods, so they cannot be used on NodeLists
.
However, there are workarounds. Again from the documentation, you can use the Array.prototype.forEach
and Array.prototype.map
methods directly like so:
var forEach = Array.prototype.forEach;
var divs = document.getElementsByTagName( 'div' );
var firstDiv = divs[ 0 ];
forEach.call(firstDiv.childNodes, function( divChild ){
divChild.parentNode.style.color = '#0F0';
});
UPDATE:
It seems NodeLists
can now be accessed like an array* in this
updated documentation:
Accessing the matches
Once the NodeList of matching elements is returned, you can examine it just like any array. If the array is empty (that is, its length property is 0), then no matches were found.
Otherwise, you can simply use standard array notation to access the contents of the list. You can use any common looping statement, such as:
var highlightedItems = userList.querySelectorAll(".highlighted");
highlightedItems.forEach(function(userItem) {
deleteUser(userItem);
});
*While you can now use forEach
, other methods like map
are not available.