Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Inheritance

Spread the love

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at inheritance.

Prototype Chaining

An object has a prototype chain.

The inherit properties from them.

For instance, we can create a chain of constructors by writing:

function Shape() {}
Shape.prototype.name = 'Shape';
Shape.prototype.toString = function() {
  return this.name;
};

function Square() {}
Square.prototype = new Shape();
Square.prototype.constructor = Square;
Square.prototype.name = 'Square';

We have the Shape constructor with some prototype properties.

Then we created a Square constructor with the prototype set to the Shape constructor.

Then we set the constructor to the Square to make instanceof sqaure returns true if we use instanceof with a Square instance.

If we want to call the parent constructor within the child constructor to populate its properties, we can change the code.

We can write:

function Shape(name) {
  this.name = name;
}
Shape.prototype.toString = function() {
  return this.name;
};

function Square(name, length) {
  Shape.call(this, name);
  this.length = length
}
Square.prototype = Object.create(Shape.prototype);
Square.prototype.constructor = Square;

to create the Shape constructor with the name property.

Then we have the Square property with the name and length parameters.

We call the Shape constructor with call and we set the first argument to this so it’s called with the Square constructor as this .

name is what we pass into the Shape constructor.

To create the prototype, we call Object.create to inherit the properties from Shape.prototype .

And we set the constructor the same way so that instanceof still reports correctly.

Class Syntax

We can make this easier with the class syntax.

With it, we can rewrite:

function Shape(name) {
  this.name = name;
}
Shape.prototype.toString = function() {
  return this.name;
};

function Square(name, length) {
  Shape.call(this, name);
  this.length = length
}
Square.prototype = Object.create(Shape.prototype);
Square.prototype.constructor = Square;

to:

class Shape {
  constructor(name) {
    this.name = name;
  }

  toString() {
    return this.name;
  };
}

class Square extends Shape {
  constructor(name, length) {
    super(name);
    this.length = length
  }
}

We use the extends keyword to inherit the properties from Shape ‘s properties in the Square class.

super(name) is the same as Shape.call(this, name); .

Prototype

We can get the prototypes in the chain with the __proto__ property.

For instance, we can write:

console.log(square.__proto__);

then we get the Shape constructor.

We can get the __proto__ of the __proto__ property, so we can get:

console.log(square.__proto__.__proto__);

then we get the Shape.prototype object.

Then if we call it again:

console.log(square.__proto__.__proto__.__proto___);

We get the Object.prototype object.

We can confirm this by writing:

console.log(square.__proto__ === Square.prototype);
console.log(square.__proto__.__proto__ === Shape.prototype);
console.log(square.__proto__.__proto__.__proto__  === Object.prototype);

Then they all log true .

Objects Inherit from Objects

Objects can inherit from other objects directly.

To do that, we use the Object.create method to return an object that returns an object with a given prototype object.

For instance, we can write:

const proto = {
  foo: 1
};
const obj = Object.create(proto);

Then we can check the prototype of obj with the __proto__ property:

console.log(obj.__proto__ === proto);

then that logs true .

Conclusion

We can create objects that inherit from other objects.

Also, we can check the prototype chain of an object to see what’s inherited from.

Then class syntax makes inheritance with constructors much more easily.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *