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

Inheritance of the prototype chain

function Parent () {
    this.parentDesc = 'This is the parent description.'
}
Parent.prototype.getDesc = function () {
    return this.parentDesc
}
Parent.prototype.parentName = 'parent'
Parent.prototype.obj = {
    name: 'Parent object'
}

function Child () {}

Child.prototype = new Parent()
Child.prototype.constructor = Child

let child1 = new Child()
// New's hidden operation child.__proto__ === child.prototype
console.log(child1.getDesc()) // 'This is a description of the parent'
let child2 = new Child()
console.log(child2.getDesc()) // 'This is a description of the parent'

// Modify the parentName attribute of the Parent
child1.parentName = 'Has the parent been renamed?'
child1.obj.name = 'Changed the value of name'

console.log(child2.parentName) // 'parent'
console.log(child2.obj.name) // select * from 'name';
Copy the code

In this code, we refer Child’s prototype object to Animal’s instance object, The __proto__ attribute of the Parent instance refers to its prototype, parent.prototype, so child.prototype = new Parent() is equivalent to child.prototype = parent.prototype, Instance objects child1 and child2 have access to properties and methods in their prototype chain. The prototype objects point to Parent. Prototype, so output child1.getdesc ().

PS: When implementing inheritance through stereotype chains, you cannot use object literals to create stereotype methods, because doing so would override the stereotype chain.

This is what we call prototype chain inheritance, which essentially refers to the prototype object of one object to the instance object of another. Then its advantages and disadvantages are self-evident.

  • Advantages: Multiple instances can share properties and methods defined on the stereotype chain.
  • Disadvantages: Each instance’s modifications to the attributes of the reference type are also shared by other instances, which is not desirable.
  • Disadvantages: Subclasses cannot take arguments to the parent constructor when instantiated.

Take a look at this chestnut:

// Create an object o from a function with attributes A and B:
function f() {
  this.a = 1;
  this.b = 2;
}
let o = new f(); // {a: 1, b: 2}

// Define attributes on the prototype of f functions
f.prototype.b = 3;
f.prototype.c = 4;
console.log(o.b) / / 2
console.log(o.c) / / 4

F = {b:3,c:4}; f = {b:3,c:4}; Prototype.__proto__ refers to Object. Prototype **/
[[Prototype]] has attributes B and C
// (o.__proto__ or O.constructor. Prototype)
/ / o. [[Prototype]] [[Prototype]] is the Object. The Prototype.
/ / the last o. [[Prototype]] [[Prototype]] [[Prototype]] is null
// This is the end of the prototype chain, null,
// By definition, null means no [[Prototype]].

// To sum up, the entire prototype chain is as follows:

// {a:1, b:2} ---> {b:3, c:4} ---> Object.prototype---> null

console.log(o.a); / / 1
// Is a a property of o? Yes, this property has a value of 1

console.log(o.b); / / 2
// is b a property of o? Yes, this property has a value of 2
// The prototype also has a 'b' attribute, but it will not be accessed.
// This condition is called "property shadowing"

console.log(o.c); / / 4
// Is c a property of o? No, let's see if it's on the prototype
[[Prototype]] // c is an attribute of o.[[Prototype]]. Yes, this property has a value of 4

console.log(o.d); // undefined
// is d a property of o? No, let's see if it's on the prototype
[[Prototype]] // d is an attribute of o.[[Prototype]]. No, let's see if it's on the prototype
// o.[[Prototype]].[[Prototype]] is null
// Find d attribute, return undefined
Copy the code

Look at this diagram

PS: The prototype understanding is not so clear can move here