preface

Inheritance is one of the most important features of JS as an object-oriented language. It is also a knowledge point often asked in interviews. Inheritance is mainly for subclasses to use all the functions of the parent class, and can extend these functions.

1. Prototype inheritance

Function Parent1() {this.name = "Parent1" this.arr = [1,2,3]} parent.say = function(){this.name = "Parent1" this.arr = [1,2,3]} console.log(this.name); } function Child1 (){ this.type = "child1" } Child1.prototype = new Parent1() let child1_1 = new Child1() let child1_2 =  new Child1() console.log(child1_1.name); // parent1 console.log(child1_1.say()); //parent1 child1_2.arr.push(4) console.log(child1_1.arr,child1_2.arr); //[1, 2, 3, 4] [1, 2, 3, 4]Copy the code

Disadvantages: All subclasses are instances processed by new construction, and the attributes of the parent class are not isolated and will affect each other

Constructor inheritance

function Parent2 (){ this.name = "parent2" } Parent2.prototype.say = function(){ console.log(this.name); } function Child2 (){ this.type = "child2" Parent2.call(this) } let child2_1 = new Child2() console.log(child2_1.say());  // TypeError: child2_1.say is not a function console.log(child2_1.name); // parent2Copy the code

Method: Use call, apply, and bind to refer this of a subclass function to a parent function. Disadvantage: Only the attributes of the parent function can be read. Methods and attributes in the prototype chain cannot be inherited

3. Combinatorial inheritance

Parent3 (){this.name = "Parent3" this.arr = [1,2,3]} parent.prototype. Say = function(){this.name = "Parent3" this.arr = [1, 3]} console.log(this.name); } function Child3 (){ this.type = "child3" Parent3.call(this) } Child3.prototype = new Parent3() let child3_1 = new Child3() let child3_2 = new Child3() child3_1.arr.push(4) console.log(child3_1.arr, child3_2.arr);Copy the code

Disadvantages: The call() method already has all the attributes of the parent class, and it will also have all the attributes of the parent class when the prototype is used later.

4. Parasitic combination inheritance

Function Parent4 (){this.name = "parent3" this.arr = [1,2,3]} parent.say = function(){this.name = "parent3" this.arr = [1, 3]} console.log(this.name); } function Child4 (){ this.type = "child4" Parent4.call(this) } Child4.prototype = Parent4.prototype Child4.prototype.constructor = Child4 let child4_1 = new Child4() let child4_2 = new Child4() child4_1.arr.push(4) console.log(child4_1.arr, child4_2.arr) // [1, 2, 3, 4] [1, 2, 3] console.log(child4_1.constructor === Child4) // true console.log(child4_1.constructor === Parent4)// falseCopy the code

To solve the problem of combination inheritance of repeated attributes, directly equalize the prototype of the subclass to the prototype of the parent class, or use object.create to inherit the prototype but do not execute the parent class constructor;

5. ES6 class inheritance

class Parent5{ constructor(){ this.name = 'Parent5' this.arr = [1, 2, 3]} say(){console.log(this.name)}} Class Child5 extends Parent5{constructor(){super( this.type="Child5" } } let child5_1 = new Child5() let child5_2 = new Child5() child5_1.arr.push(4) console.log(child5_1.say()) // Parent5 console.log(child5_1.arr, child5_2.arr) // [1, 2, 3, 4] [1, 2, 3] console.log(child5_1.constructor === Child5) // true console.log(child5_2.constructor === Parent5) // falseCopy the code

It’s the syntactic sugar of parasitic combinatorial inheritance

Source of learning