Extend Native Prototypes in Node.js

By  on  

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!

Recent Features

  • By
    7 Essential JavaScript Functions

    I remember the early days of JavaScript where you needed a simple function for just about everything because the browser vendors implemented features differently, and not just edge features, basic features, like addEventListener and attachEvent.  Times have changed but there are still a few functions each developer should...

  • By
    9 More Mind-Blowing WebGL Demos

    With Firefox OS, asm.js, and the push for browser performance improvements, canvas and WebGL technologies are opening a world of possibilities.  I featured 9 Mind-Blowing Canvas Demos and then took it up a level with 9 Mind-Blowing WebGL Demos, but I want to outdo...

Incredible Demos

  • By
    Record Text Selections Using MooTools or jQuery AJAX

    One technique I'm seeing more and more these days (CNNSI.com, for example) is AJAX recording of selected text. It makes sense -- if you detect users selecting the terms over and over again, you can probably assume your visitors are searching that term on Google...

  • By
    Facebook Open Graph META Tags

    It's no secret that Facebook has become a major traffic driver for all types of websites.  Nowadays even large corporations steer consumers toward their Facebook pages instead of the corporate websites directly.  And of course there are Facebook "Like" and "Recommend" widgets on every website.  One...

Discussion

  1. Ricardo

    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 specification

  2. MaxArt

    Never 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.

  3. “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.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!