JavaScript Inheritance Prototype Vs Class
Tags: es6, javascript, class, prototype
Published: 2019-12-10 12:31:10

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](https://www.tutorialsteacher.com/javascript/prototype-in-javascript) 
 
## Start with code rather then talking

![do_this.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1572451107454/s165n1QU7.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](https://cdn.hashnode.com/res/hashnode/image/upload/v1572540553560/CXDQgfzsG.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](https://cdn.hashnode.com/res/hashnode/image/upload/v1572540920049/fVO3n_URn.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**](https://gist.github.com/bapinmalakar/b7778a78ae7b1d13ab38462af457690f) 

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](https://cdn.hashnode.com/res/hashnode/image/upload/v1572542963871/3fU5TAit_.gif)