Prototypal Inheritance

Authors

Recap

Lets start with person constructor function .

Person.prototype.calcAge = function () { console.log(2021 - this.birthYear); }; const Person = function (name, birthYear) { this.name = name; this.birthYear = birthYear; };

This constructor function has a prototype property which is an object and inside the object we define the calcAge method and the Person.prototype also has a reference back to the Person which is the constructor property . So Person.prototype.constructor will point back to Person itself .

Person.prototype is not the prototype of Person but it is the prototype of all the objects that is created using Person constructor function .

Speaking of object creation , Lets now analyze how objects are created using new keyword and constructor functions . When we call a constructor function with new keyword things that are going to happen are -

  • A new empty object { } is created .
  • Function is called and in this call the this keyword will be set to the newly created object .
  • Newly created object is linked ( __proto __ property ) to constructor function's prototype property .
  • Function automatically returns the object.

Prototypal Inheritance

Lets understanding this with examples -

const jack = new Person('Jack', 1997); jack.calcAge();

So here we are attempting to call the calcAge function on the jack object . However Javascript cannot find calcAge function directly in the jack object .

So what happens in this situation ??

Well if a property or a method is not found in a certain object . JavaScript will look into its prototype . That's how the calcAge function can run correctly and return results and the behaviour we just describe is called Prototypal Inheritance .

So the jack object inherited the calcAge method from its prototype . We can create as many Person objects as we like and all of them will inherit methods and properties from the prototype .

Now that fact that jack is connected to a prototype and abilities of looking up methods and propertiesin a prototype is what we call the prototype chain . So the jack object and its prototype forms a prototype chain but the prototype chain does not end here .

Image of prototypal inheritance

So here is a diagram of our object linked to its prototype via __proto__ property . But now lets remember that Person.prototype itself is an object and all objects in javascript have a prototype . Therefore Person.prototype itself must have a prototype and the prototype of Person.prototype is Object.prototype .

What is happening here ?

Well Person.prototype is just a simple object which means that it has been built by the built-in object constructor function and this is the function which is called behind the scenes whenever we create an object literal . The {} are just a shortcut to write new Object() .

These entire series of links between the objects is what is called Prototype Chain and Object.prototype is usually on top of the prototype chain which means its prototype is null . So its __proto__ property will simply point to null . It is very similar to scope chain but with prototype . So whenever JavaScript cannot find a certain property or method in a certain object its going to look up into the next prototype in the prototype chain .

Lets take an example to make it clear

jack.hasOwnProperty('firstName');

So here javascript is going to start by trying to find the called method on the object itself . But ofcourse it can't find hasOwnProperty method in jack , so it will then look into its prototype which is Person.prototype . Now we didn't define any property named hasOwnProperty in Person.prototype also , so now javascript will look into Object.prototype and will find it there as hasOwnProperty is a method in Object.prototype .

Another one just to put a final nail in the coffin -

let arr = ['Sumit', 'Kumar']; console.log(arr.__proto__.__proto__ === Object.prototype); //returns true console.log(arr.__proto__.__proto__.__proto__); //return null

As we can see here whether we make an array , object or a function ,it actually down the prototype chain ends up being an object . If we create an Array it has prototype of Array.prototype and arr.__proto__.__proto__ is Object.prototype . So thats how the whole prototype chain works .