# How Prototypal Inheritance works in JavaScript

Before starting with `prototypal inheritance` let’s first understand what a prototype is.

> All the objects in JavaScript like `Array`, `Boolean`, `Date` etc all inherit properties and methods from their prototype.

`Object` is the at top of the Prototype chain means all the other objects inherit their properties and methods from `Object.prototype`.

Suppose we have `Person` object constructor:

```js
function Person(name, age) {
 this.name = name;
 this.age = age;
}
```

Then we create objects of `Person` as follows:

```js
const person1 = new Person("David", 30);
const person2 = new Person("John", 35);

console.log(person1); // {name: "David", age: 30}
console.log(person2); // {name: "John", age: 35}
```

If we want to add another property to the `Person` object we can add that to an individual object like this:

```js
person1.gender = 'Male';
```

but this will only add this property to person1 object.

```js
console.log(person1.gender); // Male
console.log(person2.gender); // undefined
```

To add the property to the `Person` object itself we have to add it to its prototype before creating objects so it will be available to all of its objects.

```js
Person.prototype.gender = 'Male';

const person1 = new Person("David", 30);
const person2 = new Person("John", 35);

console.log(person1.gender); // Male
console.log(person2.gender); // Male
```

We can also add methods to the `Person` prototype like this:

```js
Person.prototype.display = function() {
 console.log(this.name, this.age);
};

const person1 = new Person("David", 30);
const person2 = new Person("John", 35);

person1.display(); // David 30
person2.display(); // John 35
```

So to add any property or method to an object, we need to add it to its prototype.

If we compare the `person1` and `person2` display methods we will see that it returns `true`

```js
console.log(person1.display === person2.display) // true
```

> It returns true because in memory there is only a single copy of the display function because we added the method to its prototype so it's shared by all objects.

Let's see what happens when we add it directly inside the Person constructor

```js
function Person(name, age) {
 this.name = name;
 this.age = age;
 this.display = function() {
  console.log(this.name, this.age);
 };
}

const person1 = new Person("David", 30);
const person2 = new Person("John", 35);

person1.display(); // David 30
person2.display() // John 35
```

Now, let's compare the display methods:

```js
console.log(person1.display === person2.display) // false
```

Now it displays `false` because as we have added the method directly to the constructor function, each object created from `Person` will have its own copy of function so there are two copies of display function in memory here and as we create more objects, the number of copies of display function inside memory will also increase.

So it's a bad practice and it's not recommended to create methods directly inside the constructor function instead we should add them to the prototype.

Now, we have some basic knowledge of prototypes, let's understand prototypal inheritance now.

## Prototypal Inheritance

Let's start with the same `Person` example above.

```js
function Person(name, age) {
 this.name = name;
 this.age = age;
}

Person.prototype.display = function() {
 console.log(this.name, this.age);
};
```

Now, let's create an `Employee` constructor function that will inherit the properties and methods of the `Person`.

```js
function Employee(name, age, salary) {
 Person.call(this, name, age);
 this.salary = salary;
}

const emp = new Employee('Mike', 20, 4000);
```

Here, we are using `Person.call` function to call the `Person`’s constructor and pass the `name` and `age` to it.

Now, let’s check what `emp` contains:

```js
console.log(emp); // {name: "Mike", age: 20, salary: 4000}
```

As you can see, it contains all the properties of `Person` plus its own properties.

Now, let's call the display method using the `emp` object.

```js
emp.display(); //  Error: emp.display is not a function
```

Why do we get the error?

This is because we only mentioned inheriting properties of `Person` using `Person.call(this, name, age)`

To inherit methods also, we need to link the prototype and then create an object.

```js
Employee.prototype = Object.create(Person.prototype);

const emp = new Employee('Mike', 20, 4000);
emp.display(); // Mike 20
```

Now, let’s check the type of `Employee` which we can check using constructor property

```js
console.log(emp.constructor) // Person
console.log(Employee.prototype.constructor) // Person
```

It prints `Person` which is wrong because we know that, it should be `Employee`. The constructor property should always return the correct type.

Suppose, we have an array:

```js
const numbers = [1, 2, 3, 4];

console.log(typeof numbers); // "object"
```

We get an object because every array in JavaScript is an object so to get its correct type we can use `constructor` property that returns the correct type.

```js
console.log(numbers.constructor) // Array
console.log(numbers.constructor === Array) // true
```

So to fix the issue with `Employee` constructor we need to change its constructor type

```js
Employee.prototype.constructor = Employee;

console.log(emp.constructor) // Employee
console.log(Employee.prototype.constructor) // Employee
```

Now, we get the correct result.
The complete prototypal inheritance will look like this

%[https://gist.github.com/myogeshchavan97/2cdbad8abf0a2e2810fb0e2102dff77d]

As you can see, even for the simple prototypal inheritance we have to add a lot of extra code.

Therefore ES6 has added class syntax which allows us to implement the same in an easy way.

%[https://gist.github.com/myogeshchavan97/8ebfdbdfd9285820162af11a215e7290]

As you can see, the class-based syntax is short and easy to understand when compared with prototypal inheritance.

**Note**: The class at the end uses the prototypal inheritance itself. It’s just that, we don’t need to worry about it

### Thanks for reading!

Starting with ES6, there are many useful additions to JavaScript like:

* ES6 Destructuring
* Import and Export Syntax
* Arrow functions
* Promises
* Async/await
* Optional chaining operator
and a lot more.

**You can learn everything about all the ES6+ features in detail in my [Mastering Modern JavaScript](https://modernjavascript.yogeshchavan.dev/) book.**

> Check out free preview contents of the book [here](https://www.freecodecamp.org/news/learn-modern-javascript/).

Also, you can check out my **free** [Introduction to React Router](https://yogeshchavan1.podia.com/react-router-introduction) course to learn React Router from scratch.

Want to stay up to date with regular content regarding JavaScript, React, Node.js? [Follow me on LinkedIn](https://www.linkedin.com/in/yogesh-chavan97/).

[<img src="https://gist.github.com/myogeshchavan97/98ae4f4ead57fde8d47fcf7641220b72/raw/c3e4265df4396d639a7938a83bffd570130483b1/banner.jpg">](https://bit.ly/3w0DGum)

[<img src="https://cdn.buymeacoffee.com/buttons/default-yellow.png" >](https://www.buymeacoffee.com/myogeshchavan97)
