jeremygo

jeremygo

我是把下一颗珍珠串在绳子上的人

[Translation] JavaScript - Inheritance, Delegation Pattern, and Object Linking

Original Article: JavaScript — Inheritance, delegation patterns and Object linking

Author: NC Patro

Learn about inheritance, delegation patterns, and objects linked to other objects in JavaScript (prototype inheritance).

What is Inheritance#

In most class-based object-oriented languages, inheritance is a mechanism that allows one object to acquire all the properties and methods of another object. Although the class keyword was introduced in ES2015, JavaScript is not a class-based language. It is merely syntactic sugar and fundamentally still relies on the prototype chain.

Classical Inheritance vs. Prototype Inheritance#

Inheritance Diagram

Classical Inheritance (Non-JavaScript)#

  • Vehicle is the parent class, and v1 and v2 are instances of Vehicle.
  • Car is a subclass of Vehicle, and c1 and c2 are instances of Car.
  • When we inherit a class, classical inheritance creates a copy of the behavior from the parent class to the child class, and then the parent and child classes become independent entities.
  • This is like building a car using tools and car blueprints, but once they are built, they are separate entities because it is a copy and there is no connection between them. This is why all arrows point downwards (properties and behavior are passed down).

Prototype Inheritance (Delegation Pattern)#

  • v1 and v2 are linked to Vehicle.prototype because they are created using new.
  • Similarly, c1 and c2 are linked to Car.prototype, and Car.prototype is linked to Vehicle.prototype.
  • In JavaScript, when we create an object, it does not copy properties or behavior, but instead creates a link. The same applies when inheriting a class.
  • Compared to classical non-JavaScript inheritance, all the links point in the opposite direction because it is a delegation pattern. These links are called the prototype chain.
  • This pattern is called the delegation pattern and is commonly known as prototype inheritance in JavaScript.

You can refer to this article JavaScript-Prototypes for a deeper understanding of the prototype chain.

Example of Prototype Inheritance#

  • Implementing classical inheritance using Object.create().
  • In the code snippet below, Car.prototype and Vehicle.prototype are connected using the Object.create() function.
// Vehicle - Superclass
function Vehicle (name) {
    this.name = name;
}
// Superclass method
Vehicle.prototype.start = function () {
    return "engine of " + this.name + " starting...";
}

// Car - Subclass
function Car (name) {
    Vehicle.call(this, name); // Call the superclass constructor
}
// Subclass extends superclass
Car.prototype = Object.create(Vehicle.prototype);
// Subclass method
Car.prototype.run = function () {
    console.log("Hello " + this.start());
}

// Subclass instances
var c1 = new Car("Fiesta");
var c2 = new Car("Baleno");

// Access the subclass method that internally accesses the superclass method
c1.run();   // "Hello engine of Fiesta starting..."
c2.run();   // "Hello engine of Baleno starting..."
  • In the above code, due to the prototype chain, the object c1 can access the run() and start() methods. As shown in the diagram below, we can see that c1 does not have these methods, but it has a link upwards.
  • The this in the above code is simply the current execution context of each method, i.e., c1 and c2.

You can browse this article JavaScript-All About this and new Keywords for a detailed understanding of the this keyword.

Diagram representation of the above code:

JavaScript Inheritance Diagram

Objects Linked to Other Objects#

  • Now let's simplify the previous inheritance example code and focus only on the links between objects.
  • So we will try to remove the .prototype, constructor, and new keywords and only consider objects.
  • We will use the Object.create() function to create all the links between functions.

Here is a simplified version of the previous example code:

// Base object with an initialization method
var Vehicle = {
    init: function (name) {
        this.name = name;
    },
    start: function () {
        return "engine of " + this.name + "starting...";
    }
}

// Delegation link created between the sub object and the base object
var Car = Object.create(Vehicle);

// Sub object method
Car.run = function () {
    console.log("Hello " + this.start());
};

// Instance objects with delegation links pointing to the sub object
var c1 = Object.create(Car);
c1.init('Fiesta');

var c2 = Object.create(Car);
c2.init('Baleno');

c1.run();   // "Hello engine of Fiesta starting..."
c2.run();   // "Hello engine of Baleno starting..."

Diagram representation of the above code:

Object Linking

  • Now we can see how we eliminate the complexity of new, .prototype, constructor, and method invocation in the code while still achieving the same result.
  • The only important thing is that c1 is linked to one object and then linked to another object, and so on.
  • This is also known as the object delegation pattern.

Summary#

It is important to understand prototype inheritance and the prototype chain before using prototype inheritance and the prototype chain in code to avoid complexity.

Reference: You Don't Know JS series

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.