“This is the fifth day of my participation in the August More Text Challenge.

Today just update a question, this activity held in my mind šŸ˜­, although every day in hydrology

怐2怑# JavaScript review (2)

inheritance

Prototype chain inheritance

function Person() {};
// Add data to the prototype of Person
Person.prototype = {
    name: 'Person'.age: '23'
}

let a = new Person();
let b = new Person();
console.log(a.name, a.age); // Person 23
console.log(b.name, b.age); // Person 23It looks like the output is the same, but in fact, every time`new`Each instance returns a new object, so it is not equal.console.log(a === b); // false
Copy the code

While it is quite simple to implement inheritance using prototype chains, there are drawbacks:

  • The properties and methods on the prototype, which are shared by all instances, have a serious problem (directly following the code above) :
b.__proto__.name = 'b'; // When we modify the 'name' on the prototype, print the values of 'a' and 'b' again

console.log(a.name, a.age); // b 23
console.log(b.name, b.age); // b 23
Copy the code

When we change the data on the prototype through B, the data on A changes as well.

  • Moreover, inherited data is fixed and cannot be changed by parameters

Inheritance via constructors

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.say = function() {
    console.log(I was `The ${this.name}This year,The ${this.age}`.'Person');
}
function Children(name, age){
    Person.call(this, name, age);
}

let a = new Children('a'.20);
let b = new Children('b'.23);

console.log(a); // ChildrenĀ {name: "a", age: 20}
console.log(b); // ChildrenĀ {name: "a", age: 20}
console.log(a === b); // false

// Now let's see if changing the property value of one instance has any effect on the other instance objects
b.name = '123';
console.log(a); // ChildrenĀ {name: "a", age: 20}
console.log(b); // ChildrenĀ {name: "123", age: 23}

// There seems to be no problem, right? Let's now run the 'say' method.
a.say(); // a.say is not a function

/ / an error? Let's print 'a.say'
console.log(a.say); // undefined

// undefined is output
Copy the code

This is one of the deadliest problems with using constructors for inheritance. You cannot inherit properties and methods on the parent class’s prototype chain, only properties and methods declared by the parent class.

The Holy Grail model is the perfect inheritance. (Maybe I didn’t write it perfectly)

const grail = (() = > {
    // A temporary constructor is named to act as a bridge
    let Temporary = function () {};
    return (target, origin) = > {
        // The prototype of the temporary constructor is equal to the prototype of Origin
        Temporary.prototype = origin.prototype;
        // The target prototype is the Temporary instance of the orifin constructor, so when we change the target prototype properties, we change the properties of the orifin instance.
        target.prototype = new Temporary();
        // Then point the constructor on the target prototype at yourself
        target.prototype.constructor = target;
        target.prototype.super = origin.prototype; // Any prototype where we point the target prototype to Origin
    }
})();

function Person(name, age) {
   this.name = name;
   this.age = age;
};

Person.prototype.say = function () {
    console.log('Person')};function A(name, age) {
   Person.call(this, name, age);
};

grail(A, Person);
let a = new A('a'.20);
console.log(a); // AĀ {name: "a", age: 20}
a.say(); // Person
Copy the code

I may have trouble writing the final Holy Grail mode, if you see it, please let me know, thanks ~