Let\'s say I have the following list:
- Cookies
- Coffee
- Milk
-
The type of the result is a NodeList.
Since it is an Array-like object, you can run the map, forEach and other Array.prototype functions on it like this:
var result = document.querySelectorAll('a');
Array.prototype.map.call(result, function(t){ return t; })
The map, forEach, any and other functions in the Array prototype work on Array-like objects. For example, let's define an object literal with numerical indexes (0,1) and a length property:
var arrayLike = { '0': 'a', '1': 'b', length: 2};
The forEach method, applied to the arrayLike object will like on a real Array.
Array.prototype.forEach.call(arrayLike, function(x){ console.log(x) } ); //prints a and b
In the documentation, it says that :
[the returned list of elements] is a non-live
NodeListof 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
forEachormapon aNodeList?
NodeListare used very much like arrays and it would be tempting to useArray.prototypemethods on them, however they don't have those methods.JavaScript has an inheritance mechanism based on prototypes for both built–in objects (like
Arrays) and host objects (likeNodeLists).Arrayinstances inherit array methods (such asforEachormap) 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,mapand the likes are own properties of theArray.prototypeobject.Unlike arrays,
NodeListprototype chain looks like the following:
myNodeList --> NodeList.prototype --> Object.prototype --> null
NodeList.prototypecontains the item method, but none of theArray.prototypemethods, so they cannot be used onNodeLists.
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.