DEV Community

Cover image for JavaScript Inheritance Prototype Vs Class
Biplab Malakar
Biplab Malakar

Posted on

JavaScript Inheritance Prototype Vs Class

Before ES6 JavaScript doesn't support class like OOPs but we can code class and inheritance using "Prototype".

Today we are going do some code to implement inheritance using both prototype(ES5) and class(ES6).

The prototype is an object that is associated with every functions and objects by default in JavaScript, where function's prototype property is accessible and modifiable and object's prototype property (aka attribute) is not visible.
Every function and object includes prototype object by default.

-- tutorialsteacher

Start with code rather then talking

do_this.gif

A. Simple Inheritance

*Like every children has parents , so we are going to create one Parent class to manipulate and store the parent information then inherit the Child class from Parent class *

Screenshot 2019-10-31 at 10.18.48 PM.png

Using Prototype

const Parent = function(father_name, mother_name, city_name) {
  this.father_name = father_name;
  this.mother_name = mother_name;
  this.city_name = city_name;

  this.printParentDetails= ()=>{
    console.log('Father Name: ', this.father_name);
    console.log('Mother Name: ', this.mother_name);
    console.log('They live in: ', this.city_name);
  }
}

const Child = function(father_name, mother_name,city_name, name, age) {
  Parent.call(this,father_name,  mother_name, city_name);
  this.name = name;
  this.age = age;

  this.printChildDetails = ()=>{
      this.printParentDetails();
      console.log('Child name is: ', this.name);
      console.log('Child age is: ', this.age);
  }
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

const child_1 = new Child('Jonny', 'Jolly', 'New York', 'Jin', 18);
const child_2 = new Child('Ram', 'Sham', 'Mumbai', 'Jadu', 21);

child_1.printChildDetails();
child_2.printChildDetails();

Parent.call(this,father_name, mother_name, city_name)

It will bind our Parent class within the Child class context.

Child.prototype = Object.create(Parent.prototype)

Assign Parent prototype to Child Prototype

Child.prototype.constructor = Child

The constructor of Child class should be Child constructor, not Parent class constructor

Using ES6 class

class Parent {
  constructor(father_name, mother_name, city_name) {
    this.father_name = father_name;
    this.mother_name = mother_name;
    this.city_name = city_name;
  }

  printParentDetails(){
    console.log('Father Name: ', this.father_name);
    console.log('Mother Name: ', this.mother_name);
    console.log('They live in: ', this.city_name);
  }
}

class Child extends Parent{
  constructor(father_name, mother_name,city_name, name, age) {
    super(father_name,  mother_name, city_name);
    this.name = name;
    this.age = age;
  }

  printChildDetails(){
      this.printParentDetails();
      console.log('Child name is: ', this.name);
      console.log('Child age is: ', this.age);
  }
}


const child_1 = new Child('Jonny', 'Jolly', 'New York', 'Jin', 18);
const child_2 = new Child('Ram', 'Sham', 'Mumbai', 'Jadu', 21);

child_1.printChildDetails();
child_2.printChildDetails();

B. Multiple Inheritance

Like every child belongs to the country also, so we are going to create a **Country class. And the Child class going to inherit from Both Parent and Country class**

Screenshot 2019-10-31 at 10.25.05 PM.png

Using Prototype

const Parent = function(father_name, mother_name, city_name) {
  this.father_name = father_name;
  this.mother_name = mother_name;
  this.city_name = city_name;

  this.printParentDetails= ()=>{
    console.log('Father Name: ', this.father_name);
    console.log('Mother Name: ', this.mother_name);
    console.log('They live in: ', this.city_name);
  }
}

const Country = function(country_name, country_code) {
  this.country_name = country_name;
  this.country_code = country_code;

  this.printCountryDetails= ()=> {
    console.log('Country Name: ', this.country_name);
    console.log('Country Code: ', this.country_code);
  }
}


const Child = function(father_name, mother_name,city_name, name, age, country_name, country_code) {
  Parent.call(this,father_name,  mother_name, city_name);
  Country.call(this, country_name,country_code);
  this.name = name;
  this.age = age;

  this.printChildDetails = ()=>{
      this.printParentDetails();
      this.printCountryDetails();
      console.log('Child name is: ', this.name);
      console.log('Child age is: ', this.age);
  }
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype = Object.create(Country.prototype);
Child.prototype.constructor = Child;


const child_1 = new Child('Jonny', 'Jolly', 'Washington', 'Jin', 18, 'US', '+1');
const child_2 = new Child('Ram', 'Sham', 'Mumbai', 'Jadu', 21, 'India', '+91');

child_1.printChildDetails();
child_2.printChildDetails();

Using ES6 class

JavaScript class are not pure class like OOPs. JavaScript class does not support multiple inheritance and hybrid inheritance. To implement multiple inheritance, we need to do some JavaScript coding trick. We will build the same example used in above using multiple inheritance concept.

class Parent {
  constructor(father_name, mother_name, city_name) {
    this.father_name = father_name;
    this.mother_name = mother_name;
    this.city_name = city_name;
  }

  printParentDetails(){
    console.log('Father Name: ', this.father_name);
    console.log('Mother Name: ', this.mother_name);
    console.log('They live in: ', this.city_name)
  }
}

class Country {
  constructor(country_name, country_code) {
    this.country_name = country_name;
    this.country_code = country_code;
  }

  printCountryDetails() {
    console.log('Country Name: ', this.country_name);
    console.log('Country Code: ', this.country_code);
  }
}


class Child {
  constructor(father_name, mother_name,city_name, name, age, country_name, country_code) {
    extendClass(this, new Parent(father_name, mother_name,city_name));
    extendClass(this, new Country(country_name, country_code));
    this.name = name;
    this.age = age;
  }

  printChildDetails(){
      this.printParentDetails();
      console.log('Child name is: ', this.name);
      console.log('Child age is: ', this.age)
  }
}

function extendClass(child, parent) {
  for(let key in parent){
    child[key] = parent[key]
  }
  Reflect.ownKeys(Reflect.getPrototypeOf(parent)).filter(d=> d!= 'constructor').map(fun=>{if(!child[fun]) {child[fun] = parent.__proto__[fun].bind(child);}});
}


const child_1 = new Child('Jonny', 'Jolly', 'New York', 'Jin', 18);
const child_2 = new Child('Ram', 'Sham', 'Mumbai', 'Jadu', 21);

child_1.printChildDetails();
child_2.printChildDetails();

extendClass(this, new Parent(father_name, mother_name,city_name))

This extendClass will bind our Parent class into Child class. It will accept two parameter, first one will be current object means Child class and second one will be instance of Parent class

for(let key in parent)

Loop over all the members of Parent class **and bind them into **Child Class

Reflect.getPrototypeOf(parent)

It will return a prototype object of the parent class, means all the member functions of the parent class.

Reflect.ownKeys(Reflect.getPrototypeOf(parent))

Retrieve all the functions name from prototype object.

filter(d=> d!= 'constructor').map(fun=>{if(!child[fun]) {child[fun] = parent.proto[fun].bind(child);}})

Assign prototype of the** Parent class** to the child class, except *Parent class Constructor
*

For full code click here

So finally we implement inheritance using both prototype(ES5) and class(ES6). Incase of any query comment box are always open for you and its also freeπŸ˜„πŸ˜„βœŒοΈ

giphy.gif

Top comments (0)