Classical and Prototypical inheritance in JavaScript

Danny Cornelisse
23-02-2017

The simplest use of inheritance in JavaScript is the ability to create a new object, or instance,  that inherits all properties from another (parent) object. We want to do this because we are lazy, we don’t want to write the same piece of code over and over again. Instead, we want to write the code once, and then create new instances of our object as many times as we like. Using inheritance makes our code reusable, readable and therefore clean.

Classical inheritance

In the following way, you can create a constructor using classical inheritance:

 /** 
 * Create function that you want to create instances of
 * (note the capitalized variable name)
 */
 
var Human = function(name, age){
    this.name = name;
    this.age = age;
}

// Create new instances(!) of Human
var henk = new Human("Henk", 100), 
    rodrigo = new Human("Rodrigo", 30);

Henk and Rodrigo are both new instances of Human. They both have a name and an age.

Let’s say our Human Henk is not a normal human, but a developer. Most humans have a facebook account. Henk doesn’t have Facebook because he doesn’t trust big companies. We can overwrite that property for just Henk:

var Human = function(name, age){
    this.name = name;
    this.age = age;
    this.hasFacebook = true;
}

// Create new instances(!) of Human
var henk = new Human("Henk", 100), 
    rodrigo = new Human("Rodrigo", 30);
    
// Change henk's hasFacebook propery
henk.hasFacebook = false;

console.log(henk.hasFacebook); // false
console.log(rodrigo.hasFacebook); // true

In the example above we see that initially, Henk inherits the hasFacebook property from Human, but that we can change the value if we like to false.

Prototypical inheritance

Prototypical inheritance is a little difference. Rather than a function, we just create a new object:

/**
 * Create new human object
 * (no capitalization needed!)
 */
 var human = {
     hasFacebook: true;
 }
 
 // Create new instances (!) of human
 var henk = Object.create(human),
     rodrigo = Object.create(human);

So we see that we can create new objects by using human as a prototype.

But WAIT!?! Henk doesn’t have a name, and age, how do I add those??

 var human = {
     hasFacebook: true,
     giveName: function(name){
         this.name = name
     },
     giveAge: function(age){
         this.age = age;
     }
 }
 
 // Create new instances (!) of human
 var henk = Object.create(human),
     rodrigo = Object.create(human);
     
 henk.giveName("Henk");
 henk.giveAge(100);
 rodrigo.giveName("Rodrigo");
 rodrigo.giveAge(30);
 
 // Or just one method:
 human.create = function(name, age){
     this.name = name;
     this.age = age;
 }
 henk.create("Henk", 100);
 rodrigo.create("Rodrigo", 30);

Using the .prototype property on constructors

In order to use prototypes with constructors you can use the prototype property:

var Human = function(){
}
Human.prototype.eyes = 2;

var henk = new Human(), 
   rodrigo = new Human();

Rather than using this.eyes  = 2, we can use the Human.prototype.eyes. This creates only one instance of ‘eyes’ in the prototype, instead of henk.eyes and rodrigo.eyes in their own respective

So I can just choose which one I prefer?

No.

Classical and prototypical inheritance are very different. Therefore you also have to consicder which one to use. The biggest advantage of using prototypical inheritance is that you can create a new instance of any object, even if that object is already a new instance of another object:

var human = {
    eyes: 2
}
var developer = Object.create(human);
var henk = Object.create(developer);

console.log(henk.eyes);//2

Henk inherits the eyes property all the way from the human object. With classical inheritance, this is a little bit more difficult. We would have to create a function where you can extend other constructors in a new constructor.

There is a lot more to inheritance than I just explained, but I hope I gave a basic idea about it. Ofcource, in ES6 it is a lot easier to create classes and extend them to multiple subclasses, but for browser support you can use these ‘normal’ ways of inheritance. In the future I hope to write more blog posts about classes and prototypes, so see you then!

A good read: http://aaditmshah.github.io/why-prototypal-inheritance-matters/#constructors_vs_prototypes
A good watch: https://www.youtube.com/watch?v=doXpW5AD60Q&list=PLoYCgNOIyGABs-wDaaxChu82q_xQgUb4f&index=7

LEAVE A REPLY

1 Comment

you might also like