JS has no concept of classes; all classes are essentially functions. Both ES5 and ES6 inheritance mechanisms essentially rely on stereotype chains, except that ES5 is explicitly declared and ES6 uses syntactic sugar classes.

ES5 inheritance mode

To explore inheritance in OOP, we start with the concept of prototype chains. With the prototype chain, we can achieve some inheritance, but it’s not perfect because there are two problems with the prototype chain.

  1. When a stereotype chain contains a stereotype that references a value of a type, the value of that reference type is shared by all instances.
  2. When creating an instance of a subclass, we cannot pass arguments to the constructor of the parent class.

Borrowing constructor

To solve this problem, we can use the helper constructor method, which is implemented by calling the parent class’s constructor in the subclass’s constructor.

function Parent() {this. Numbers = [1, 2, 3]. }function Child(){ Parent.call(this); } var child1 = new Child(); child1.numbers.push(4); Console. log(child1.numbers) // 1,2,3,4 var child2 = new Child(); The console. The log (child2. Numbers) / / 1, 2, 3Copy the code

Obviously, the superclass constructor solves both of these problems at a single blow: first, it ensures that the values referenced in the prototype chain are independent, and second, the subclass can also pass arguments to the superclass when it is created. The problem with this approach, however, is that methods are defined in constructors, so function reuse becomes impossible and subclasses of methods defined by the parent class cannot access them. To solve this problem, the classic ES5 inheritance method composite inheritance emerged.

Combination of inheritance

The basic idea of combinatorial inheritance is to use prototype chain to inherit prototype attributes and methods, and to inherit instance attributes by borrowing constructors.

// ES5 inheritance (most widely used)function Parent(value){
    this.value = value;
}

Parent.prototype.getValue = function(){
    console.log(this.value);
}

functionChild(value){ Parent.call(this, value); } Child. Prototype = new Parent(); // Inherit the superclass method and call the superclass constructor againCopy the code

This is classic inheritance, combining the advantages of using constructors and prototype chains, but there is one problem: the Parent class constructor is called twice. Is there any way to avoid this? The answer must be yes.

Parasitic combinatorial inheritance

Parasitic combinatorial inheritance appears to reduce the overhead of calling superclass constructors. The idea is that you don’t have to call the constructor of a supertype to specify the stereotype of a subtype.

functionextend(Child,Parent){ var prototype = object(Parent.prototype); Prototype. Constructor = Child; // Add object Child. Prototype = prototype; // Specify the object}Copy the code

ES6 inheritance mode

ES6 inheritance is implemented with only one standard pattern, which is much clearer than ES5. First, we need to add the class keyword for the parent and child classes, although this is just a syntactic sugar. In addition, the extends keyword indicates an inheritance relationship between a parent class and a subclass. Another special point is constructor and super, where subclasses must use the super method in their constructors. Because subclasses don’t have their own This object, they get the parent’s this object through the super method.

class Animal{
    constructor(props){
        this.name = props.name || 'unknown';
    }
    
    eat(){
        console.log(this.name + " will eat pests");
    }
}

class Bird extends Animal{
    constructor(props, myProps){
        super(props);
        this.type = props.type || 'unknown';
        this.attr = myProps;
    }
    
    fly(){
        console.log(this.name + " can fly!");
    }
    
    show(){
        console.log(this.type + "..." + this.attr);
    }
}

var bird = new Bird({
    name: "Jack".type: "Little Sparrow"
}, "I am a bird."); bird.eat(); bird.fly(); bird.show(); // Jack will eat pests // Jack can fly! // Little sparrow... I am a birdCopy the code