Extend Native Prototypes in Node.js
As someone who was on the legendary MooTools JavaScript team, I have some affection for extending the prototypes of native objects. Of course the practice of extending prototypes is taboo these days as browser vendors are iterating and implementing new specs more quickly than the IE6 era, but extending natives in Node.js could be considered safer as, in theory, we have more control over the environment (Node.js version).
Extending a native within Node.js is fairly simple:
// Inside a file module called "String.prototype.startsWith.js" // Naming convention important for maintenance and clearness of intent // This is a very, very simple shim not made for production use // It's simply to illustrate the prototype extension // More logic should be added for edge cases if(!String.prototype.startsWith) { String.prototype.startsWith = function(term) { return this.substr(0, term.length) === term; }; } // ---------- // Inside any other module that wants to use the extension require('String.prototype.startsWith'); // Usage if(myString.startsWith('Moo')) { // ... }
As long as you require the the module that contains the extension code, the native will have its desired additional method. Of course this doesn't just apply to natives, you can extend other Objects in this same fashion. If you scour npm you can find loads of prototype extensions, one being String.prototype.startsWith, which also work in client side code.
I presume I'll receive some haterade for suggesting this practice being more OK with Node.js so have at me!
In fact, I don’t see much problem extending String/Array/… objects in client side code. When the browser supports it, then the polyfill will not be used.
About extending host objects (
DOMElement
…), the main problem was IE6-7. Recent browsers have no problem with it, even if that does not belong to the specificationNever had any problem extending native prototypes, but there are a few caveats:
– you either polyfill standard methods (like
startsWith
above) or use names that won’t probably be used by future standard developments, such as vectorDotProduct;– don’t abuse this technique: changing prototypes is *slow* and also user-defined methods in the prototype chain are;
– unless you make a module out of your extensions, remember that your code will be less reusable.
“extending natives in Node.js” should “be considered safer as, in theory,” upgrading Node.js breaks everything :P
Kidding, my v0.11 to v4 upgrade was actually pretty smooth.