NodeList.prototype.forEach = Array.prototype.forEach;
Asked Answered
A

4

18

Do you see any problems with the following:

NodeList.prototype.forEach = Array.prototype.forEach;

Normally forEach is just a property of arrays, but by setting it as a property of all NodeLists as well, there's no need to convert a NodeList to an array before you can loop through its nodes with forEach.

Ainsley answered 7/3, 2013 at 9:21 Comment(2)
I liked this idea.. Waiting if others point out any problems in it.Gusti
Check out NodeList.jsCull
L
7

It's often not a good idea to extend the functionality of DOM through prototypes, especially in older versions of IE (article).

However, you can simply use Array.prototype.forEach even without adding it to the prototype chain or converting your NodeList into an array:

var list = document.querySelectorAll(".some.query");
Array.prototype.forEach.call(list, function(el){ /* ... */ });

/* or */
var forEach = function(ctn, callback){
    return Array.prototype.forEach.call(ctn, callback);
}
forEach(list, function(el){ /* ... */ });

See also MDN: Why can't I use forEach or map on a NodeList.

Lilybel answered 7/3, 2013 at 9:38 Comment(5)
there are so many features of JS that would work perfectly well, if it weren't for older versions of IE...Brackish
why did you use Array.prototype.forEach.call(... instead of just Array.prototype.forEach(... when in syntax at MDN it says you can define this in 2nd parameter. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… I'm just trying to improve my understanding.Undesigning
@MuhammadUmer: Please don't ask questions in comments. If I wasn't active on StackOverflow anymore, you would never get an answer. That being said, thisArg is the value of this during callback, not during Array.prototype.forEach.Lilybel
Question asked, thanks for time... if you want to explain more please do.. #25802434Undesigning
Unfortunately this approach didn't work for me for nodes of the XML document, i.e. retrieved via XMLHttpRequest or using jQuery $.get("/test.xml", function(xmlDocument) { Array.prototype.forEach.call(xmlDocument.childNodes, function(node) {...}); });. However solution from this post works fine: Array.from(xmlDocument.childNodes).forEach(function(node) {...});. For nodes of the DOM document it works fine: NodeList.prototype.forEach = Array.prototype.forEach; document.childNodes.forEach(function(node) { ... });. FF v45, Chrome v53.Kilah
N
2

If you're working on a library that will be used by other people then it's not a good idea to do this.

If it's just your own code (i.e.. a website) then I guess it's no big deal. You should probably guard it though because in the future browsers will support NodeList.prototype.forEach natively (Chrome does already).

if (!NodeList.prototype.forEach) {
  NodeList.prototype.forEach = Array.prototype.forEach;
}
Nitroso answered 28/8, 2016 at 14:38 Comment(0)
W
0

As Zeta mentioned, it would be better to use a convenience function. This version, however, will allow you to give it context.

var forEach = function(list, callback, context){
  return Array.prototype.forEach.call(list, callback, context);
};
Wilcher answered 3/12, 2013 at 17:17 Comment(0)
P
0

NodeList.prototype.forEach() is now available in most browsers: https://developer.mozilla.org/fr/docs/Web/API/NodeList/forEach

Browser compatibility table: https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Browser_Compatibility

Prophecy answered 24/6, 2020 at 17:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.