Last Updated: February 25, 2016
·
1.719K
· steveniseki

Inheritance in JavaScript it's all prototypal

We all know that JavaScript uses prototypal inheritance instead of the classical type. Even though we all use advanced MVC frameworks like AngularJs or Ember.js which make great use of prototypal inheritance, it is still easy for us to get confused whenever someone asks us to explain inheritance in JavaScript.

Mozilla has an excellent guide on Inheritance and the prototype chain which is probably the link to refer someone to if they ask the dreaded question... When it comes to inheritance, JavaScript only has the one great construct: objects. Each object has an internal link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype, the final link in the prototype chain.

<b>Inheriting properties and methods in JavaScript</b>

JavaScript objects are dynamic bags of properties and each one has a link to a prototype object. In JavaScript, any function can be added to an object in the form of a property, and in this form it is known as a method. An inherited function acts just as any other property. When an inherited function is executed, the value of this points to the inheriting object.

<b>Creating objects that inherit properties</b>

There are many approaches to creating objects inheriting from other objects in JavaScript, the most common approaches are to use either the new keyword, or to use Object.create()

<b>Constructor</b>

A "constructor" in JavaScript is a function that is called with the new operator.

function Person(name) {
  this.name = name;
}

Person.prototype.printName = function () {
    console.log(this.name);
}

var me = new Person("Steven");
me.printName();

<b>Object.create()</b>

ECMAScript 5 introduced Object.create. Calling this method creates a new object with the specified prototype object and properties.

var a = { message: 'I am an a'}; 
var b = Object.create(a);
b.message = 'I am now a b';

It is essential to understand the prototypal inheritance model before writing complex code that makes use of it. It is also interesting for us to understand, why we actually care about inheritance in the first place. According to Crockford there are two main reasons.

<b>Type convenience</b>

We want the language system to automatically cast references of similar classes. This is important in strongly-typed languages, but is irrelevant in loosely-typed languages like JavaScript, where object references never need casting.

<b>Code reuse</b>

It is common to have a set of objects all implementing exactly the same method. Classes make it possible to create these objects from a single set of definitions. It is also common to have similar objects differing only in a few methods. Classical inheritance is useful for this, however prototypal inheritance can also be very useful for this.

As we have shown, in JavaScript, objects are easily extended. A new member can be added to an object by simple assignment. Because objects in JavaScript are so flexible, it is important to think differently about class hierarchies. Deep hierarchies are inappropriate. Shallow hierarchies are more expressive.

<b>Classes in EcmaScript 6</b>

EcmaScript 6 introduces language support for classes with the <i>classes</i>, <i>constructors</i>, and the <i>extend</i> keyword for inheritance.

class Car {
    constructor(make) { 
        this.make = make;
        this.currentSpeed = 50;
    }
}

class RaceCar extends Car { 
    constructor(make, topSpeed) {
        super(make);
        this.topSpeed = topSpeed;
    }

    goFast(){
          this.currentSpeed = this.topSpeed;
    }
}

let corvette = new RaceCar('Corvette', 150);
corvette.goFast();

JavaScript is prototypal in nature, so the question must be raised, "Do we need classical inheritance in JavaScript?" I will not go into much detail here, Nicholas Zakas has an excellent article on this topic. As Nicholas mentions, the current ECMAScript 6 class proposal is simply new syntax on top of the current prototypal patterns currently in common use in JavaScript. Inheritance works the same as always, prototype chaining, methods added to prototypes, and properties declared in the constructor.