Inheritance in JavaScript - Part 1
Tags: javascript, webdev
Published: 2021-04-28 01:52:38

Inheritance in JavaScript is based on the concept of *prototype* and the chaining of said prototypes. All JavaScript objects have a special property called *prototype*, which is a reference to another object. From this reference an object can inherit methods and properties. Any JavaScript object has its own *prototype* as well as its parent object and so on, making a chain.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vb3mo5uhy5ic2lmhknxz.jpg)

There are multiple ways to build this chain. In this post I'm going to talk about the functional approach to make a prototype chain. In future posts I will discuss *constructor functions* and *classes*.

JavaScript has the method `Object.create()` that receives two parameters: a *prototype*, and an object which contains the properties of the child to be created.

```javascript
const jet = {
  fly: function () {
    console.log("flying at: " + this.speed);
  },
};
```

This `jet` object is a plain JavaScript object created with the curly braces syntax. The prototype of `jet` is `Object.prototype`, which is an internal object provided by JavaScript.

```javascript
const combatJet = Object.create(jet, {
  shoot: {
    value: function () {
      console.log("shooting: " + this.weapon);
    },
  },
});
```

The first parameter passed to `Object.create` is the `jet` object. The second parameter is another object which has the properties we want to add to `combatJet`. When the `combatJet` object is instantiated, `combatJet.prototype` will be the `jet` object, and `combatJet` will have the `shoot` property.

```javascript
const f18 = Object.create(combatJet, {
  speed: { value: "Mach 1" },
  weapon: { value: "Minigun" },
});
```

The same thing happens when creating the `f18` object, but we are using the `combatJet` as its prototype. Also, we are adding the `speed` and `weapon` properties to the child object.

The resulting prototype chain is:

- `Object.prototype` is the prototype of `jet`
- `jet` is the prototype of `combatJet`
- `combatJet` is the prototype of `f18`

```javascript
f18.shoot(); // Prints "flying at: Mach 1"
f18.fly(); // Prints "shooting: Minigun"
```

 When calling `f18.shoot()` the `f18` object doesn't have the property `shoot`. Then, JavaScript will check if their prototype (`combatJet`) has it. `combatJet.shoot` has a reference to `this.weapon`. Typically, the `this` keyword refers to the object on which the method was called. Thus, in `f18.shoot()` the `shoot` property refers to `combatJet.shoot`, but `this.weapon` has the value of `f18.weapon`. 
 
The result of the function call will be `"shooting: Minigun"`

The same situation occurs when calling `f18.fly()`

- Look for `fly` in `f18`. It doesn't have the property
- Look for `fly` in `combatJet` which is the *prototype* of `f18`. It doesn't have the property either
- Look for `fly` in `jet` which is the _*prototype*_ of `combatJet`. It _does_ have the property
- Execute the function `fly`. `this` refers to `f18`, so `this.speed` has a value of `"Mach 1"`. The function call will print `"flying at: Mach 1"`

The instantiation of a `combatJet` object could be refactored to a function for ease of use.

```javascript
function createCombatJet(speed, weapon) {
  return Object.create(combatJet, {
    speed: { value: speed },
    weapon: { value: weapon },
  });
}
```