Prototype Inheritance in JavaScript

The Prototype is the most confusing concept in Javascript. Let’s understand it step by step.

Step 1: What is a Prototype?

Whenever we create an object of any function in javascript, all the properties and methods of that function referring to this will be inherited into the object.

Quick example:

function Person(){
  //Properties will be a part of object(s)
  this.name = "John Doe";
  this.age = 23;
  this.printName = () => {
    return this.name, this.age;
  }
  
  //Properties will not be a part of the object(s)	
  let gender = "Male"
  let dob =  "31-12-1992"
  
  
}

//Print all values
var obj = new Person();
console.log('name',obj.name) // John Doe
console.log('age',obj.age) // 23
console.log('print name function',obj.printName()) // John Doe, 23
console.log('gender',obj.gender) // Undefined
console.log('dib',obj.dob) // Undefined

In the above example properties declared with this keyword is inherited into an object. Properties and methods declared with this keyword are basically added into the prototype  which is  Person.prototype when we do something like:

Person.prototype.height = 5.5

Person.prototype.getHeight = () => {
   console.log(Person.prototype.height)
}

var obj = new Person()
obj.height // 5.5
obj.getHeight() // 5.5

The above snippet is nothing but adding a new property into an existing function’s prototype, and these properties or methods  will be available into an instance of an object (obj).

 

2. What is Inheritance?

In Javascript, you can achieve Multi Level Inheritence by using a prototype. What are we going to acheive now is if we have a function Parent, and we have a function Child, When we do objectOfChild instanceof Parent then this should return true.

Let’s acheive it through an example!

We have function Parent as shown in the snippet below:

function Parent(name, address) {
  this.fatherName = name || "unknown";
  this.fatherAddress = address || "Unknown";
}


//We have added this function into Parent prototype
Parent.prototype.PrintParent = function () {
  console.log("In Parent",this);
}

Now we have a function Child which will inherits the property from the Parent. And instance of the Child will return true when we check it through the instanceOf keyword.

function Child(name, address) {
  This will inherits all the properties and  methods of the parent
  Parent.call(this, "Nafees", "Delhi")

  this.childName = name
  this.childAddress = address
}

// This will make the Child instance of the Parent
Child.prototype = new Parent();

//If constructor not set to a Child then Child constructor will automatically be a Parent
Child.prototype.constructor = Child;

We will create one more function GrandChild which will inherits the properties and methods of the Child. since Child has the property of the Parent then GrandChild will have the properties and methods of Child as well as from Parent.

 

function GrandChild(name, address) {
  Child.call(this, "Sufiyan", "Ghatkopar")
  this.grandChildName = name
  this.grandChildAddress = address
}

// Again, This will make the GrandChild instance of the Child
GrandChild.prototype = new Child();

//If constructor not set to a grandchild then Grandchild constructor will automatically be a Child
GrandChild.prototype.constructor = GrandChild;

GrandChild.prototype.PrintGrandChild = function () {
  console.log("In Grand Child",this);
}

The idea behind creating a three levels is to achieve three level inheritence from GrandChild. Now when we do GrandChild instanceOf Child this will return true, When we will do GrandChild instanceOf Parent then this will return true.

Let’s see the out put of  all the above code in One Shot.

 

var gc = new GrandChild("A","B");
console.log("Grand child object:",gc) 
//Output: GrandChild {fatherName: "Nafees", fatherAddress: "Delhi", childName: "Sufiyan", childAddress: "Ghatkopar"…}

console.log("Grand child constructor:",gc.constructor)
//Output: Grand child constructor: ƒ GrandChild()
console.log("gc instanceof GrandChild:",gc instanceof GrandChild)
//Output: gc instanceof GrandChild:true
console.log("gc instanceof Child:",gc instanceof Child)
//Output: gc instanceof Child:true

console.log("gc instanceof Parent:",gc instanceof Parent)
//Output: gc instanceof Parent:true
var c = new Child("Sufiyan","Ghatkopar");
console.log("Child object:",c)
//Output: Child {fatherName: "Nafees", fatherAddress: "Delhi", childName: "Sufiyan", childAddress: "Ghatkopar"…}
console.log("Child constructor:",c.constructor)
//Output: Child constructor: ƒ Child()
console.log("c instanceof Parent:",c instanceof Parent)
//Output:  instanceof Parent: true
console.log("c instanceof GrandChild:",c instanceof GrandChild)
//Output: c instanceof GrandChild: false
var p = new Parent("Nafees","Delhi");
console.log("Parent object:",p)
//Output: Parent object:Parent {fatherName: "Nafees", fatherAddress: "Delhi"}
console.log("Parent constructor:",p.constructor)
//Output: Parent constructor: ƒ Parent()
console.log("p instanceof Child:",p instanceof Child)
//Output: p instanceof Child: false
 
console.log("p instanceof GrandChild:",p instanceof GrandChild)
//Output: p instanceof GrandChild: false

Complete code for the inheritence is given below:

 

 

Playground

Thank you!!