JavaScript Prototypes and Class Inheritance
Tags: javascript, beginners
Published: 2020-07-14 17:50:21

Javascript is object-based. Understanding the object system is very crucial to write a better, flexible, and robust application. 

##Not Your Typical Object System
It's important to note that javascript's object system is different from other major languages.
<blockquote>
<p>Javascript's object system is prototype based.</p>
 <p>Major languages like Python, C#, Java are class based</p>
</blockquote>
So it's important to keep in mind that javascript's object system has a different mechanism than other commonly used ones.

##Create a protypical object
Let's create an object using prototypes-

```javascript
//here Vehicle is a constructor function to create Vehicle Object
let Vehicle = function (hasEngine) {
    this.hasEngine = hasEngine
}

//every js object has prototype. let's add a method to it
Vehicle.prototype.getDetails = function () {
    return `Vehicle Details------ Any Engine: ${this.hasEngine}`
}
```
Now **getDetails()** method is a part of Vehicle object via the prototype.
This code below will create a new object with Vehicle constructor and assign the values. 
```javascript
//the new keyword creates an object with Vehicle constructor
let vehicleOne = new Vehicle(true)

 //remember we added the getDetails method to Vehicle using prototype;
//here we invoke it
console.log(vehicleOne.getDetails())

//OUTPUT
Vehicle Details------ Any Engine: true
```

##Prototypical Inheritance
Now let's take it one step further. Besides creating object using prototype we can use it for inheritance. This way of doing is known as **prototypical inheritance.**
Let's create a Car object that inherits from Vehicle-
```javascript

let Car = function (hasEngine, model, color) {
    //hasEngine will belongs to Vehicle so we call it 
    //and attach it to this Car object
    Vehicle.call(this, hasEngine)

    this.model = model
    this.color = color
}

//Car will use Vehicle's prototype; thus will get the getDetails method
Object.setPrototypeOf(Car, Vehicle.prototype)

Car.prototype.getCarInfo = function () {
    return `Car Details------ Model: ${this.model}, Color: ${this.color}, Any Engine: ${this.hasEngine}`
}

//calling the Vehicle actually calls the constructor
let carOne = new Car(true, 'Model X', 'Black')
console.log(carOne.getCarInfo())

//OUTPUT
Car Details------ Model: Model X, Color: Black, Any Engine: true
```
What this code does is essentially give the Car object to access to Vehicle prototypes. This will allow Car object to having the methods and properties of Vehicle object.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6fstia13s825l90zxknu.jpg)

#Be Aware
Using ES6+ class syntax the code can be written as follows-
```javascript
class Vehicle {
    constructor(hasEngine) {
        this.hasEngine = hasEngine
    }
    //method
    getDetails() {
        return `Vehicle Details------ Any Engine: ${this.hasEngine}`
    }
}

//calling the Vehicle actually calls the constructor
let vehicleOne = new Vehicle(true)
console.log(vehicleOne.getDetails())

//inherit
class Car extends Vehicle {
    constructor(model, color) {
        super(true)
        this.model = model
        this.color = color
    }
    carDetails() {
        return `Car Details------ Model: ${this.model}, Color: ${this.color}, Any Engine: ${this.hasEngine}`
    }
}

//calling the Vehicle actually calls the constructor
let carOne = new Car('Model X', 'Black')
console.log(carOne.carDetails())
```
The output is the same. So one might think this is the exact same thing as a prototypical inheritance; which is pretty wrong.
Using class syntax is like mimicking Java or C#'s class-based inheritance using js prototypical inheritance. 
**Class-based inheritance is always dangerous; it's wise to use composition. Yet in js using the class syntax we are mimicking the dangerous class inheritance. It's something that should be avoided at any cost.**

##Quote from Eric Elliot
<blockquote>
<p>Using class inheritance in JavaScript is more like driving your new Tesla Model S to the dealer and trading it in for a rusted out 1973 Ford Pinto.</p>
</blockquote>