JavaScript’s prototypal inheritance

In our current project we are using JavaScript for a component which should be deployed on iOS, Android and also on server side. JavaScript is a quite facinating language because it hides its true functional nature quite well and provides gotchas which traps the unwary.

In 2008, I’ve read the book “JavaScript – The good parts” from Douglas Crockford. In chapter 3 the beget method is introduced, which creates a new function with a given prototype:

if (typeof Object.beget !== 'function') {
   Object.beget = function(o) {
      var F = function() {};
      F.prototype = o;
      return new F();
    }
}

The advantages of the beget method:

  • The prototype chain is setup correctly
  • The programmer doesn’t have to use the new keyword in order to create a new object.

But why could the new keyword be so dangerous ?

If the programmer ommits the new keyword when calling a constructor function, no object will be created. Instead undefined will be returned. In addition the global context might be polluted, because the global context will become the invocation context (also known as this variable). The following example shows what happens when new is ommitted:

var Product = function(id) {
   this.id = id;
}

var p = Product(3);
console.log(p);  // --> undefined
console.log(id); // --> 3

So, the beget method prevents these errors and embraces prototypal inheritance. But there is an alternative: John Resig (and also others) presented a way to support pseudo-classical inheritance in JavaScript. I thought about to use it, but I came to the conclusion that it seems to be quite overengineered for our project. In addition the JavaScript community discussed the pseudo-classical inheritance controversial. Douglas Crockford wrote on his website:

The “super” idea is fairly important in the classical pattern, but it appears to be unnecessary in the prototypal and functional patterns. I now see my early attempts to support the classical model in JavaScript as a mistake.

In a comment on his own blog, John Resig sums it up quite well:

The usefulness of one method vs. another is debatable. If you’re just doing simple stuff then just use straight prototypal inheritance – there’s no reason to have any extra overhead. However when it comes time to stuff like super methods you’ll need some construct to make it happen.

So I wanted to use this beget method in my JavaScript code to use prototypal inheritance. But then I’ve found out, that this method found its way into the language itself as Object.create. Great 🙂

If you want to dig further into the prototype chain, consider the excellent book “You Don’t Know JS: this & Object Prototypes“.