A Brief Talk on JavaScript Parasitic Combination Inheritance

  • 2021-11-10 08:46:55
  • OfStack

Combinatorial inheritance

Combinatorial inheritance, also known as pseudo-classical inheritance, combines the prototype chain and embezzlement constructor we talked about yesterday, and combines the two points in one case. Its basic idea is to use prototype chain to inherit the attributes and methods on the prototype, and inherit the attributes of instances by stealing constructors. This advantage is that the methods can be defined on the prototype for reuse, and each instance has its own attributes.


    function SuperType (name) {
        this.name = name;
        this.colors = ["red","yellow","bule"];
    }
    SuperType.prototype.sayName = function(){
        console.log(this.name)
    }
    function SubType(name,age){
        SuperType.call(this,name);
        this.age = age;
    }
    SubType.prototype = new SuperType();
    SubType.prototype.sayAge = function(){
        console.log(this.age);
    }
    let instancel = new SubType("jackson",22);
    instancel.colors.push("pink");
    instancel.sayName(); // "jackson"
    instancel.sayAge();//22
    console.log(instancel.colors);// ["red", "yellow", "bule", "pink"]
    
    let instance2 = new SubType("bear", 20);
    console.log(instance2.colors); // ["red", "yellow", "bule"]
    instance2.sayName(); // "bear";
    instance2.sayAge(); // 20

Do you have a feeling of being suddenly enlightened in the above code? SubType calls SuperType, passes name, and then defines its own attribute age. In addition, SubType. prototype is also assigned a bit SuperType instance. After the prototype is assigned, the sayage method is added to the prototype, thus creating two subType instances, both of which have their own attributes and can share the same method.

Composite inheritance makes up for the shortcomings of prototype chain and embezzlement of constructors, and is the most used inheritance mode in js.

Parasitic inheritance

Parasitic inheritance wraps an object with a function and returns a call to that function, which becomes an instance or object that can add properties at will. object. create () is the principle.


  //  Parasitic inheritance 
    function subobject(obj) {
        let clone = Object(obj);
        clone.sayName = function(){
            console.log("jackson")
        };
        return clone;
    }
    let sub = {
        name:"bear"
    }
    let sup = subobject(sub);
    sup.sayName();//jackson

This example returns a new object based on the sub object, and the returned sup object has the properties and methods of sub, as well as a new method sayName ().

Parasitic inheritance is also suitable for scenarios that mainly focus on objects, but don't care about types and constructors. The object () function is not required for parasitic inheritance, and any function that returns a new object can be used here.

Note that adding a function to an object through parasitic inheritance makes the function difficult to reuse, similar to the constructor pattern.

Parasitic combined inheritance

Composite inheritance has this definite efficiency problem, and its parent class constructor will always be called twice, once when creating the word class prototype, and once in the subclass constructor. Essentially, subclasses only need to rewrite their prototypes at execution time.


     function inheritPrototype(subType, superType) {
        let prototype = Object(superType.prototype); //  Create an object 
        prototype.constructor = subType; //  Enhancement object 
        subType.prototype = prototype; //  Assignment object 
    }

This inheritPrototype () function implements the core logic of parasitic composite inheritance. This function takes two arguments: a subclass constructor and a parent class constructor. Inside this function, the first step is to create a copy of the parent class prototype. Then, set the constructor property to the returned prototype object to solve the problem that the default constructor is lost due to overwriting the prototype. Finally, the newly created object is assigned to the prototype of the subtype. As shown in the following example, calling inheritPrototype () can implement the subtype prototype assignment in the previous example:


function SuperType(name) {
        this.name = name;
        this.colors = ["red", "blue", "green"];
    }
    SuperType.prototype.sayName = function () {
        console.log(this.name);
    };

    function SubType(name, age) {
        SuperType.call(this, name);
        this.age = age;
    }
    inheritPrototype(SubType, SuperType);
    SubType.prototype.sayAge = function () {
        console.log(this.age);
    };

The SuperType constructor is only called once, which avoids unnecessary and unnecessary attributes on SubType. prototype, so it can be said that this example is more efficient. And the prototype chain remains unchanged.

Summarize


Related articles: