Search code examples
javascriptdomlibrariesprototypal-inheritance

Why not add Array.prototype methods onto NodeList.prototype in 2017?


Why (if at all) should I avoid doing this:

if (NodeList.prototype.map === undefined) {
    NodeList.prototype.map = Array.prototype.map
}

or anything else from here (I am not referring to []., I know it's slow)

As far as I know, this behavior was popular in the Prototype 1.0 and Mootools era, and was used with reckless abandon, only to quickly be depreciated because of inconsistencies between browsers.

Seems to work fine now, especially for such a conservative use. Should we still steer clear?


Solution

  • Because, in the event that NodeList ever gets a standard map method, it would conflict with yours.

    Even if you check whether a current method exists, for example by checking to see if the prototype holds undefined before assigning a replacement, the people who write web standards have to make sure that their changes don't break our (meaning web authors') working code. Backwards compatibility is one of the core principles of the open web; we trust that if we write code today and leave it for a week or even a few years, it should still work.

    Prototype and Mootools became problematic for this very reason; they were incredibly popular and they didn't hesitate to modify the prototypes of built-ins as they saw fit.

    Ever wonder why .contains() is instead named the less familiar .includes() on both strings and arrays? Oh, yeah, that was because Mootools had already defined .contains() and the new standard ended up breaking a significant number of existing web pages by defining an inconsistent implementation.

    TL;DR: It probably doesn't matter for any single page, but it can become a big issue when used by a popular library so people tend to avoid the practice altogether.