Prototype, Classes and More
Tags: javascript, beginners, programming
Published: 2021-07-26 10:22:44

# Introduction

Prototype is an important part of JavaScript, it gives objects the ability to inherit properties and methods from other objects. Classes makes inheritance easier as it provides an easier syntax.

Let's look into it...

So, where is the prototype, the prototype can be found on the properties on any object.

if you ``console.log()`` the following example, we can see that the prototype is a property:

```javascript
const myObj = {
    x: 100,
    y: 200,
}

console.log(myObj);
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dy14skeidlps5hwz9qut.PNG)

The prototype is there as another property for the object we just created ``__proto__: Object``, but as shown on the example above there is a value being exposed on the ``__proto__``, this is the ``Object.prototype``. But how did that get in there, If you check inside the object we can see other properties and methods that have been inherited by default from the ``Object.prototype``. This is called the prototype chain. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mxnhtthpm50fve4g4uz8.PNG)

# What is the prototype chain

Each object has a property called ``__proto__`` which is the link to another object as their prototype. This property inherits all the properties and methods from the object that has been used in the prototype. Let's follow up on the example above.

Here there we will create another object with ``Object.create()`` which creates an object and sets the prototype to the object passed as argument. Then set a property of ``z`` to ``50`` in the newly created object.

```javascript
const myObj = {
    x: 100,
    y: 200,
}

const anotherObj = Object.create(myObj);
anotherObj.z = 50;

console.log(anotherObj);
```

Once the object is created the prototype chain will be set. by expanding the property ``__proto__`` on the developer tools it's evident that it has correctly inherited the ``x`` and ``y`` properties from the other object. See Image Below.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sskc5f7lqvp14py4e1of.PNG)

In the prototype chain it's visible that the other object still inherits from the ``Object.prototype``.

This happens because ``Object.protoype`` will always be at the top of the prototype inheritance chain, this means that the ``__proto__`` for ``Object.prototype`` is ``null``.

The way the object was created with ``Object.create()`` was by using other object as a prototype but there are other ways to create a inherit the prototype of an object.

# ES5 and ES6 

Now that we have a better understanding of what the prototype, let's see the two approaches that we have to creating objects and prototype inheritance in ES5 and ES6.

## Constructors

We can either use constructor functions or the constructor method in classes to create objects. In order to create the object instance we have to use the ``new`` keyword.

```javascript
// ES5
function MyObj() {
    this.x = 100;
    this.y = 200
}

const obj1 = new MyObj();

console.log(obj1)
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfr0cxlvrcs8n0d4g6c7.PNG)

```javascript
// ES6
class MyObj {
    constructor() {
        this.x = 100;
        this.y = 200
    }
}

const c1 = new MyObj();

console.log(c1);
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idp5ldqi9mqrrdi1x6yt.PNG)

both of the examples above yield the same results except that the constructor for the newly created objects points to either the ``constructor function`` or the ``constructor()`` method in the class

## Inheritance

Now let's see the steps to inherit properties and methods in another object by using constructor functions, the ES5 way.

- Create the parent constructor function.

```javascript
function MyObj(x, y) {
    this.x = x;
    this.y = y;
}
```
- Add Desired Methods to the constructor function prototype.

```javascript
MyObj.prototype.sum = function() {
    return this.x + this.y;
}
```

- Create the child constructor function and execute the parent constructor inside the child constructor by using ``MyObj.call(this, x, y)``

```javascript
function AnotherObj(x,y,z) {
    MyObj.call(this, x, y);
    this.z = z;
}
```

Another way to execute the parent constructor inside the child constructor is the following. but this will only work because later on we will be calling the child constructor.
```javascript
function AnotherObj(x,y,z) {
    Object.getPrototypeOf(AnotherObj.prototype).constructor.call(this, x ,y)
    this.z = z;
}
```

- Set the child object prototype to the parent object in order inherit the methods that were added previously in the parent constructor function.

```javascript
AnotherObj.prototype = Object.create(MyObj.prototype);
```

- Reset the child constructor to be itself.

```javascript
AnotherObj.prototype.constructor = AnotherObj;
```

- Create a new instance of the child object.

```javascript
const anotherObj1 = new AnotherObj(100, 200, 50);
```

When we console log the instance we get the following structure in the prototype chain. Which shows that we have inherited the properties and methods from the parent object.

```javascript
console.log(anotherObj1);
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8b1sfpvjybvz3g60yrkh.PNG)

We can do this more efficiently with ES6 classes. 

- Create parent class with constructor and methods.

```javascript
class MyObj {
    constructor() {
        this.x = 100;
        this.y = 200
    }

    sum() {
        return this.x + this.y;
    }
}
```
- Create child class and execute the parent constructor by calling
``super(x,y)``.

```javascript
class AnotherObj extends MyObj {
    constructor(x,y,z) {
        super(x,y);
        this.z = z;
    }
}
```

- Create instance

```javascript
const anotherObj1 = new AnotherObj(100, 200, 50);
```

Once we console log the newly created object we see the same results

```javascript
console.log(anotherObj1)
```

The only difference is that the constructor is the class rather than the function constructor.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gy9phu8uum9zdsv3aaoa.PNG)

I hope it is useful as it was useful to me in order to gain deeper understanding in the topic. Thank you for reading. Share your feedback. and let me know if you feel something is not right. Happy Coding!