Prototypal Inheritance in JavaScript

Posted by Nishant on 17, Mar 2015

Introduction

JavaScript is the most widely used programming language, however a large number of programmers keep working with JavaScript without knowing the nuances of it. Inheritance support in JavaScript is another such feature which often confuses programmers who learn JavaScript as their secondary programming language and come from OOP background like C# and Java.

This post is my effort to elucidate inheritance in JavaScript, how and why it's useful and all the moving part which make it work, and lastly how to mimic the classical inheritance model in JavaScript.

Prototypal Inheritance

Functions are the first class objects in JavaScript, what does that mean? It means Functions get special treatment everywhere in the language. Let's consider a very simple function as shown below:

function Animal() {

}
var animal = new Animal();

As simple as the code written above is, it does fairy complex things underneath. "Function" is a global function and every function in JavaScript is an object of "Function" function, yes and that's not a typo.

Things which happen after the above piece of code is called can be visualized as shown in the following diagram:

prototypal inheritance

While reading further please keep in mind that, a) All javascript functions have "prototype" property. b) All javascript objects have an internal link "proto" and it refers to that object's constructor function's prototype. (Keep reading it will be clear).

Let's go through the above diagram in a little more detail.

  1. Animal function object is created.
  2. Animal gets assigned a property named prototype and a new object is assigned as the value of Animal object's prototype property, I'll refer to this object as Animal.prototype.
  3. Animal.prototype object get a property named constructor which points back to the Animal function object itself.
  4. Animal.prototype object has an internal link to another object, which can be retrieved by its __proto__ property. This internal linking does all the magic which enables the inheritance in JavaScript. __proto__ of Animal.prototype points to another object which is nothing but the Object.prototype.
  5. Since Object and Animal both are javascript functions and also an object of global function Function, both have internal link __proto__ which points to Function.prototype.
  6. __proto__ property of Object.prototype points to null.
  7. null object is where the inheritance chain ends.
  8. For each function call like new Animal(), a new object will be created and all such objects will have the internal link __proto__ to Animal.prototype.
  9. Finally where does Function.__proto__ link points to? well it points to the same object which Function.prototype points to.

Note: Use of proto is debatable because it was not originally included in the ECMASCRIPT specification but in ECMASCRIPT 6 it has been included in the specification and has been standardized. There are other ways we can access the link object, I'll mention those methods later in this article.

When we create a new object of function Animal using new Animal(), then a new empty object is created and Animal.prototype is set to its internal link __proto__.

What's the Deal with Internal Link "proto"?

The internal link __proto__ we have seen above does all the magic called Prototypal inheritance in JavaScript. When we try to access any property (or method) of an object in JavaScript, then JavaScript walks through the entire chain of objects using internal link __proto__ to find that property, till it finds the property in any of the objects or reaches the "null" object.

In prototypal inheritance object inherit properties from object dynamically this is different from classical inheritance where Classes (blueprints of objects) inherit from other Classes.

That's a very powerful feature of JavaScript and that makes it so cool.

Let's take another example:

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

Person.prototype.age = 24;
var person1 = new Person("Mike");

In the above piece of code, we have created a simple constructor function "Person". Theoretically, any function in JavaScript can act like a constructor function and by convention, we name constructor functions starting with a capital letter. However constructor functions are only useful if they are written in a certain way. I'll discuss more about them later in this article.

We add "age" property to functions prototype. Next let's create an object of this function using new keyword "person1", and print out all the properties of person1 using the following piece of code:

for (var p in person1) {
    if (person1.hasOwnProperty(p)) {
        console.log(p);
    }
}

Output or the above code is "name" unsurprisingly. So we can see we have only "name" property in person1 object. Let's run the following piece of code.

console.log(person1.age);?

And we can see it does print out 24, so even though person1 object does not have age property, we can still access its value because its prototype has that property.

Accessing any Object's Prototype As shown earlier, you can access it using __proto__ property. You can also access any objects prototype using Object.getPrototypeOf method like:

var person2 = new Person("Hussey");
var personProto = Object.getPrototypeOf(person1);

Remember from the earlier discussion every function's prototype has "constructor" property which points back to the function itself, and also we can access any object's prototype's property directly from object, utilizing these two facts we can access object's prototype like:

person2.constructor.prototype

Creating Custom Inheritance Chain Using Objects

This is a pretty straight forward way of creating the inheritance, let's create two objects x and y using object literals, and make x parent of y using Object.setPortotypeOf method, as shown in the code below:

var x = { name: "Mike" };
var y = { age: 27 };
Object.setPrototypeOf(y, x);

That's all that is needed to create working inheritance from one object to another. Here object y is derived from object x.

Using Constructor Functions

Constructor functions are the normal JavaScript functions written in a certain way. Constructor functions are called using new keyword. When we call a constructor function using new, a new object is created and that object is passed to the function as its context (this). We can access any function's context using this keyword, inside function's body.

In object orientated languages like C#, to create inheritance, a class (blueprint of an object) is derived from another class as opposed to the case we have seen in an earlier section where one object is derived from another object. We can mimic the similar classical inheritance in JavaScript using constructor functions. Let's see how.

Let's take the classic example of Employee and Manager inheritance. Here Employee is parent and Manager is child. We will write a very simple constructor function which represents the blueprint of Employee object as shown below:

var Employee = function (organization) {
    this.organization = organization;
}

Employee.prototype.getOrganization = function () {
    console.log(this.organization);
}

Next, let's create Manager constructor function, keeping in mind that it will be derived from Employee, we will pass Employee constructor function and its parameters as parameters of Manager function as shown below:

var Manager = function (department, parentArg1, parentFn) {
    this.department = department;
    parentFn.call(this, parentArg1);
}

Manager.prototype.getDepartment = function () {
    console.log(this.department);
}

In the next step, we need to establish the prototypal relation between Employee and Manager functions. Based on our understanding from earlier discussion, we know that we need to set internal link (proto) from child function's prototype to parent functions prototype, let's write a helper method to do exactly that, as shown below:

function CreateInheritance(child, parent) {
    for (var p in parent) {
        if (parent.hasOwnProperty(p)) {
            child[p] = parent[p];
        }
    }

    var tempProto = function () { this.constructor = child; };
    tempProto.prototype = parent.prototype;
    child.prototype = new tempProto();
}

In the next step, let's use this utility function to actually create the relation and create an instance of Manager:

CreateInheritance(Manager, Employee);

var mgr = new Manager("HR", "A WonderFull Company", Employee);

Now mgr object inherits properties and behavior from the Employee and Manager both and you can access those as if they belong to the object itself.

Conclusion

As you can see, it's not very intuitive and seems to be quite a lot of work to make classical inheritance work in JavaScript, but it's certainly possible. Also ECMASCRIPT6 specifications does introduce concept of class in JavaScript however it's just a syntactic sugar and the internal working still remains the same. JavaScript's support of prototypal inheritance is one of the greatest features of it, and it certainly helps to know how exactly it works.