Prototypal Inheritance and Difference between New and Object.create
By: Zamurd Ali
Tags: Prototype Chain, JavaScript, Prototype, Javascript Development

First thing first why bother.

Understanding core helps the mind to take easy on things otherwise it keeps on floating in mind what kind of black magic is going on. Prototype Inheritance is the core thing of javascript where most of the magic is happening. Classes are not just synthetic sugar on top of ‘Prototypal Inheritance’ for detail read but in the end, it does utilize the prototype inheritance. Classes make it more readable instead of using old fashioned manual prototyping. This post will discuss the core concept behind the classes in JavaScript.

let’s start by demystifying what prototype and __proto__ properties are.

Each javascript function ( also known as constructor functions ) has a prototype property which is used to create __proto__ property on objects. This __proto__ is the object which is then used in the lookup chain.

You can verify which prototype is used to create the object.

Object.prototype.isPrototypeOf({}) // true

Function.prototype.isPrototypeOf(()=>{}) // true

what this means is ({}).__proto__ === Object.prototype any object has properties and methods available to it which are available on Object that's where toString and many other functions come from on your object, same is the case for (()=>{}).__proto__ === Function.prototype now as the function is also an instance of Object so Object.prototype.isPrototypeOf(Function) is also true. We discussed this because both new and Object.create are used to create and initialize a new object with __proto__ property attached to it but in different ways.

On a lighter note main difference between new and Object.create is that for new we need a constructor function and for Object.create we use objects to create a new object. let see what MDN web docs say’s about new keyword.

The new operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has a constructor function.

Consider this.

function Human({ name, age }){

this.name = name;

this.age = age;

}

Human.prototype.getInfo= function(){

console.log(`human ${this.name} is ${this.age} year old`)

}

The keynote here each function has a prototype property is assigned to it which is an object that object has a property called constructor which is linked back to the original function this is important in setting this (will discuss in a separate post). Whenever a new keyword is used on the constructor function it will create a new object and use the prototype of constructor function as __proto__ of newly created object (will discuss shortly how this is used in inheritance along with Object.create shortly ) as prototype is an object we can attach functions/properties to it. Object.create is used for implementing inheritance. As per MDN web docs

‘The Object.create() method creates a new object, using an existing object as the prototype of the newly created object.’

It’s easy to remember if we take it as ‘ The Object.create() method creates a new object and sets the provided object as __proto__ property on newly created object, that is the second main difference between Object.create and new keyword. This __proto__ property is used under the hood to keep things intact. Consider following.

function Programmer({skills}){

this.skills = skills

}

This will have same structure as above with prototype property having a constructor pointing back to function. Here we have target to extend Programmer from Human. So the trick is to update prototype property, we have two options

1- Programmer.prototype = new Human({ name:’a’, age:31 });

2- Programmer.prototype = Object.create(Human.prototype);

By simply looking into it we can say that 1st option doesn’t make much sense (It does give us access to functions that are available on Human prototype) so we will go with the second option leaving object to be initialized later, Object.create will create new object and whatever is in Human.prototype will be available on __proto__ property of that newly created object. Now Programmer.prototype.__proto__ === Human.prototype is valid. We will add one method on Programmer.

function Programmer({name,age,skill}){

this.skill = skill

Human.call(this,{name,age})

} Programmer.prototype = Object.create(Human.prototype) Programmer.prototype.getGirl = function(){

console.log(`No you don't`)

}

We called Human just to attach properties of Human to this scope of Programmer. Following is visual representation.

let obj = new Programmer({name:’zoomi’,age:31,skill:’javascript’})

We have our object which has access to its parent Human properties and methods. Explore followings

Human.prototype.isPrototypeOf(Programmer.prototype) //true

Human.prototype.isPrototypeOf(obj) // true

All this can be done in ES6 with following.

class Human {

constructor({name,age}){

this.name = name;

this.age = age;

}

getInfo= function(){

console.log(`human ${this.name} is ${this.age} year old`)

}

}

class Programmer extends Human{

constructor({name,age,skill}){

super({name,age})

this.skill = skill

}

getGirl = function(){

console.log('no you don\'t')

}

}