This is the 9th day of my participation in the August More Text Challenge. For details, see:August is more challenging
Inherit from the constructor
Calling the constructor
In the last article, we mentioned that in stereotype inheritance, there are problems with attributes of reference types because stereotype properties and methods are shared. To solve this problem, developers started using a technique called borrowing constructors. The idea is simple: call the constructor of the parent type inside the constructor of the child type. We can execute the constructor on the newly created object by using the apply() or call() methods, as shown below:
function Father(){ this.colors= ['red','pink', 'green']} function Son(){// inherit Father father.call (this)} var son1 = new Son(); son1.colors.push('yellow'); console.log(son1.colors); // Output: red,pink,green,yellow var son2 = new Son(); console.log(son2.colors); // Output: red,pink,greenCopy the code
In the code father.call () borrows the constructor of the parent type. The Father constructor is called in the context of the newly created Son instance via the call() method (or apply() method), so that all object initialization code defined in the Father() function is executed on the Son object. Therefore, Each instance of Son will have its own copy of the colors attribute.
Passing parameters
A big advantage of borrowing constructors over the prototype chain is that you can pass arguments from the constructor of a subtype to the constructor of the parent type, as shown in the following example
function Father(name){ this.name = name; } function Son(){ Father.call(this,'Alvin'); this.age = 18; } var son = new Son(); console.log(son.name); // Output: Alvin console.log(son.age); // Output: 18Copy the code
The Father value in the above code takes a parameter, name, which is assigned directly to the name attribute. When you call the Father constructor in the Son constructor, you actually set the name attribute for the instance of Son. To ensure that the Father constructor does not override the properties of the subtype, you can add the properties in the subtype after the parent constructor is called.
The problem of borrowing constructors
If you just borrow the constructor, you can’t avoid the problem with the constructor pattern: methods are defined in the constructor, so function reuse is impossible. And methods defined in the parent type’s stereotype are invisible to the subtype. So all types can only use the constructor pattern. It is generally not recommended to use the borrowed constructor technique alone.
Combination of inheritance
As we learned earlier, there is a reference type problem with prototype chain inheritance, and the problem of function reuse and prototype method inheritance cannot be realized by borrowing constructors. So can you combine the two, take its essence, discard its dross? The answer is yes. That’s what we’re going to talk about next: composite inheritance.
Composite inheritance, sometimes called pseudo-classical inheritance, refers to an inheritance pattern that combines a chain of archetypes with techniques that borrow constructors to maximize the best of both. The idea is to use the stereotype chain to inherit the attributes and methods of the stereotype. The inheritance of instance properties is achieved by borrowing constructors. This enables function reuse by defining methods on the prototype, while ensuring that each instance has its own properties. Let’s look at an example
function Father(name){ this.name = name; this.colors = ['red','pink','green']; } father.prototype. sayName = function(){console.log(this.name)} function Son(name, age){// name); this.age = age; } // Method inheritance Son. Prototype = new Father(); Son.prototype.sayAge = function(){ console.log(this.age); } var son1 = new Son('Alvin', 28); son1.colors.push('yellow'); console.log(son1.colors); // red,pink,green,yellow son1.sayName(); //Alvin son2.sayAge(); //28 var son2 = new Son('Semon', 29); console.log(son2.colors); //red,pink,green son2.sayName(); //Semon son2.sayAge(); / / 29Copy the code
In this example, the Father constructor defines two properties: name and colors, and the Father stereotype defines a method, sayName(). The Son constructor passes the name argument to the Father constructor and then defines its own property, age. The instance of Father is then assigned to the stereotype of Son, and the method sayAge() is defined on that new stereotype. This allows two different Son instances to have their own properties and use the same method.
Composite inheritance avoids the pitfalls of prototype chains and borrowed constructors, and combines their advantages to become the longest used inheritance pattern in JavaScript.