Click here to Skip to main content
15,886,067 members
Articles / Programming Languages / Javascript

Prototypal Inheritance in JavaScript

Rate me:
Please Sign up or sign in to vote.
3.39/5 (13 votes)
17 Mar 2015CPOL6 min read 25.2K   14   15
This article explains how the inheritance chain works in JavaScript using prototypes and how to implement custom inheritance similar to classical programming model.

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:

JavaScript
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:

Image 1

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:

JavaScript
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:

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

JavaScript
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

  1. As shown earlier, you can access it using “__proto__” property.
  2. You can also access any objects prototype using Object.getPrototypeOf method like:
    JavaScript
    var person2 = new Person("Hussey");
    var personProto = Object.getPrototypeOf(person1);
  3. 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:
    JavaScript
    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:

JavaScript
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:

JavaScript
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:

JavaScript
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:

JavaScript
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:

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
I am a technology lover and software engineer by profession. I enjoy writing code and I work on .NET, JavaScript, NodeJs, Microsoft Azure and other related web technologies.

Comments and Discussions

 
GeneralI like your diagram Pin
Mihai Manole27-Mar-15 1:30
Mihai Manole27-Mar-15 1:30 
QuestionMy vote is 5 Pin
ashayms25-Mar-15 5:55
ashayms25-Mar-15 5:55 
SuggestionVery dangerous... Pin
Kornfeld Eliyahu Peter25-Mar-15 0:10
professionalKornfeld Eliyahu Peter25-Mar-15 0:10 
GeneralRe: Very dangerous... Pin
Nitij25-Mar-15 0:20
professionalNitij25-Mar-15 0:20 
AnswerRe: Very dangerous... Pin
Mihai Manole25-Mar-15 3:26
Mihai Manole25-Mar-15 3:26 
GeneralRe: Very dangerous... Pin
Nishant_Chaturvedi25-Mar-15 4:02
Nishant_Chaturvedi25-Mar-15 4:02 
GeneralRe: Very dangerous... Pin
Kornfeld Eliyahu Peter25-Mar-15 4:43
professionalKornfeld Eliyahu Peter25-Mar-15 4:43 
GeneralRe: Very dangerous... Pin
Mihai Manole29-Mar-15 10:46
Mihai Manole29-Mar-15 10:46 
QuestionYour diagram is wrong Pin
Mihai Manole24-Mar-15 10:30
Mihai Manole24-Mar-15 10:30 
AnswerRe: Your diagram is wrong Pin
Nishant_Chaturvedi24-Mar-15 18:02
Nishant_Chaturvedi24-Mar-15 18:02 
BugRe: Your diagram is wrong Pin
Mihai Manole24-Mar-15 21:32
Mihai Manole24-Mar-15 21:32 
GeneralRe: Your diagram is wrong Pin
Nishant_Chaturvedi25-Mar-15 20:22
Nishant_Chaturvedi25-Mar-15 20:22 
QuestionMy vote of 3: First explain classes, and then inheritance Pin
Gerd Wagner19-Mar-15 4:39
professionalGerd Wagner19-Mar-15 4:39 
AnswerRe: My vote of 3: First explain classes, and then inheritance Pin
Nishant_Chaturvedi19-Mar-15 7:19
Nishant_Chaturvedi19-Mar-15 7:19 
AnswerRe: My vote of 3: First explain classes, and then inheritance Pin
Mihai Manole27-Mar-15 2:15
Mihai Manole27-Mar-15 2:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.