Snakes and Coffee Snakes and Coffee - 1 year ago 63
Javascript Question

Why doesn't nodelist have forEach?

I was working on a short script to change

elements' inner text, but found that
does not have a
method. I know that
doesn't inherit from
, but doesn't it seem like
would be a useful method to have? Is there a particular implementation issue I am not aware of that prevents adding

Note: I am aware that Dojo and jQuery both have
in some form for their nodelists. I cannot use either due to limitations.

Answer Source

None of these answers explain why NodeList doesn't inherit from Array, thus allowing it to have forEach and all the rest.

The answer is found on this es-discuss thread. In short, it breaks the web:

The problem was code that incorrectly assumed instanceof to mean that the instance was an Array in combination with Array.prototype.concat.

There was a bug in Google's Closure Library which caused almost all Google's apps to fail due to this. The library was updated as soon as this was found but there might still be code out there that makes the same incorrect assumption in combination with concat.

That is, some code did something like

if (x instanceof Array) {
} else {

However, concat will treat "real" arrays (not instanceof Array) differently from other objects:

[1, 2, 3].concat([4, 5, 6]) // [1, 2, 3, 4, 5, 6]
[1, 2, 3].concat(4) // [1, 2, 3, 4]

so that means that the above code broke when x was a NodeList, because before it went down the doSomethingElseWith(x) path, whereas afterward it went down the otherArray.concat(x) path, which did something weird since x wasn't a real array.

Fortunately, there is hope. The DOM standard now includes an Elements class that is a real subclass of array. This isn't implemented anywhere yet (largely because ES6 subclassing isn't implemented anywhere yet). But when it is, we'll finally have a good alternative to NodeList.