The Inheritance in JavaScript

Approaches of creating objects in purpose of code reuse

August 26, 2015

Recently, I was learning a deeper level of JavaScript by reading the book JavaScript Patterns, which I would recommend to every JavaScript beginner, as it briefly summarized the core concepts and specific features without explaining the basic syntax. The Chapter 6 in the book explains Code Reuse Patterns, and I will list all the patterns I could see in this post and keep updates and appending new patterns to the list.

You see several ways to do “clas- sical” and nonclassical inheritance. But it’s important to keep the end goal in mind— we want to reuse code. Inheritance is one way (means) for us to reach that goal. And it’s not the only way.

Classical Inheritance

In JavaScript Patterns, the ‘perfect’ classical inheritance pattern is called proxy constructor, which is derived by other four patterns with apparent drawbacks. Generally why we should structure code like this:

function inherit(C, P) {
    var F = function () {};
    F.prototype = P.prototype;
    C.prototype = new F();
    C.uber = P.prototype;
    C.prototype.constructor = C;
}

Lots of posts have explained the details of this pattern as well, and here is one example on how to use it.

Prototypal Inheritance

In ECMAScript 5, the prototypal inheritance pattern becomes officially a part of JavaScript, and is implemented through the method Object.create(). You just need to add a shim on swithing to a classical inheritance pattern if the browsers (e.g. IE 8) do not support Object.create().

ES6 Style Inheritance

In ECMAScript 6, class was introduced to the language as syntax suger, which makes JavaScript look like Java, however, the objects are still linked via prototype rather than class. Check here to see ES6 equivalents in ES5.

class Hello {
  constructor(name) {
    this.name = name;
  }

  hello() {
    return 'Hello ' + this.name + '!';
  }

  static sayHelloAll() {
    return 'Hello everyone!';
  }
}

class HelloWorld extends Hello {
  constructor() {
    super('World');
  }

  echo() {
    alert(super.hello());
  }
}

var hw = new HelloWorld();
hw.echo();

alert(Hello.sayHelloAll());

Factory Constructor Pattern Inheritance

This post explains what Factory Constructor Pattern is, and here is the other post expaining why factory pattern is over classical pattern.

Inheritance by copying properties

It’s worth noting that there are no prototypes involved in this pattern at all; it’s only about objects and their own properties.
function extendDeep(parent, child) { var i,
toStr = Object.prototype.toString, astr = "[object Array]";
child = child || {};
for (i in parent) {
if (parent.hasOwnProperty(i)) {
if (typeof parent[i] === "object") {
child[i] = (toStr.call(parent[i]) === astr) ? [] : {}; extendDeep(parent[i], child[i]);
} else {
child[i] = parent[i]; }
} }
return child; }

Inheritance by libraries

The extend method in libraries like Underscore, Lodash, and jQuery could be a good idea of inheritance if one of them is included in your project.

Conclusion

I cannot see which pattern is better now, and what I will do is to try all of them in my side projects to feel the diff in depth.

By deeper understanding the inheritance in JavaScript, I found there two articles are quite useful, in which the main argument actually is whether or not we should avoid using new keyword or classical inheritance in JavaScript: