This is the 8th day of my participation in Gwen Challenge

Constructor inheritance

We learned about the advantages and disadvantages of prototype chain inheritance in the last article. Now that we know the advantages, we need to carry forward the disadvantages, and to solve this disadvantage, we will use the constructor inheritance we will learn about next.

  • How it works: In the constructor of a subclass, call the parent constructor by apply or call to implement inheritance.

Without further ado, just (generation) art (code) :

function Parent(parent){
    this.parent = parent
}
Parent.prototype.getName = function(){
    console.log(this.parent)
}
function Child(name,child){
    Parent.call(this, name)
    this.child = child
}

let child1 = new Child('I am child1'.'well!')
console.log(child1) // {parent: 'I am child1', child:' yes '}
let child2 = new Child('I am child2'.'oh oh')
console.log(child2) // {parent: 'I am child2', child:' yes '}
console.log(child1.getName) / / an error
console.log(child1 instanceof Parent) // false
console.log(child1 instanceof Child) // true
Copy the code

In the above code, you can see that two disadvantages of prototype chain inheritance are addressed, but this approach also has its drawbacks:

  • An instance is not an instance of a parent class, only an instance of a subclass.
  • A subclass cannot inherit a method from its parent class’s prototype chain.
  • The parent function is executed each time a subclass instance is generated.

Combinatorial inheritance (a combination of stereotype chain inheritance and borrowed constructor inheritance)

Combination inheritance, sometimes called pseudo-classical inheritance, refers to an inheritance pattern that combines a chain of archetypes and techniques borrowed from constructors to take advantage of the best of both. The idea is to use the prototype chain to achieve inheritance of prototype attributes and methods, and to achieve inheritance of instance attributes by borrowing constructors. This enables function reuse by defining methods on prototypes, while ensuring that each instance has its own attributes.

// Parent class: human
    function Person () {
      this.head = 'Brain melon seeds';
      this.emotion = ['or'.'angry'.'哀'.'music']; // All men have joys and sorrows
    }
    // Put the methods in the Person class to be shared in prototype for reuse
    Person.prototype.eat = function () {
      console.log('Eat and drink');
    }
    Person.prototype.sleep = function () {
      console.log('sleep');
    }
    Person.prototype.run = function () {
      console.log('run');
    }
    // Subclass: student, inherits the "person" class
    function Student(studentID) {
      this.studentID = studentID;
      Person.call(this);
    }
    
    Student.prototype = new Person();  // Student. Prototype constructor is overridden, resulting in stu1.constructor === Person
    Student.prototype.constructor = Student;  // Redirect the constructor pointer to the Student prototype object to the Student itself

    var stu1 = new Student(1001);
    console.log(stu1.emotion); //[' happy ', 'angry ',' sad ', 'happy ']

    stu1.emotion.push('sorrow');
    console.log(stu1.emotion); //[" joy ", "anger "," sorrow ", "joy "," sorrow "]
    
    var stu2 = new Student(1002);
    console.log(stu2.emotion); //[" happy ", "angry "," sad ", "happy "]

    stu1.eat(); // Eat and drink
    stu2.run(); / / run
    console.log(stu1.constructor);  //Student
Copy the code

In the code above, we extract the reusable methods from the Person class into Person.prototype, and then set Student’s prototype object as an instance of the Person class so that STU1 can access the properties and methods on the Person prototype object. Second, we use the Person.call (this) method in the Student constructor to ensure that stu1 and STU2 have their own copies of the parent property. Therefore, the combination of stereotype chain inheritance and borrowed constructor inheritance perfectly solves the previous shortcomings of both.