Determination of the relationship between prototype and instance

  1. Instanceof: Instanceof returns true if a response constructor has been present in an instance’s prototype chain
function Person(){}
const person = new Person()
console.log(person instanceof Person)   // true
Copy the code
  1. IsPrototypeOf (): Each prototype in the prototype chain contains this method, which returns true as long as there is a prototype in the prototype chain
function Person() {}
const person = new Person()
console.log(Person.prototype.isPrototypeOf(person))  // true
Copy the code

inheritance

1. Prototype chain inheritance

Function Parent() {this.name = 'old' this.color = ['red', 'black'] } Parent.prototype.getName = function () { console.log(this.name) } function Child() {} Child.prototype = new Parent() var child1 = new Child() child1.color.push('yellow') console.log(child1.color) // ['red', 'black', Var child2 = new Child() console.log(child2.color) // ['red', 'black', 'yellow'] child2.getName() // old timeCopy the code

Advantages: Methods that can share prototypes Disadvantages:

  1. Properties of reference types are shared by all instances
  2. When creating an instance, you cannot pass arguments to the parent class

Constructor inheritance

How it works: Calls the superclass constructor in the subclass constructor

function Person(name) {
    this.name = name
    this.color = ['red'.'yellow']}function Children(name, age) {
    Person.call(this, name)
    this.age = age
}

const child1 = new Children('Old times'.22)
child1.color.push('black')
console.log(child1)   // Children {name: 'old ', color: ['red', 'yellow', 'black'], age: 22}
const child2 = new Children('十一'.25)
console.log(child2)   // Children {name: '11 ', color: ['red', 'yellow'], age: 25}
Copy the code

As shown in the code above, a newly created instance does not modify its internal attributes without affecting the attributes of other instances:

  • In the subclass constructor you can pass arguments to the superclass constructor
  • This ensures that the referenced type values in the prototype chain are independent and will not be shared by instances

Disadvantages:

  • Methods are defined in the constructor and are created each time an instance is created

3. Combinatorial inheritance

Principle: Combines prototype chain and constructor inheritance, bringing together the elements of both. Using stereotype chains to inherit properties and methods on stereotypes and instance properties through constructors, you can either define methods on stereotypes for reuse or have each instance have its own properties.

function Person(name) {
  this.name = name
  this.color = ['red'.'yellow']}// Define methods on prototypes that can be reused later
Person.prototype.sayName = function () {
  console.log(this.name)
}

function Children(name, age) {
  Person.call(this, name)
  this.age = age
}
// This step is used to inherit methods
Children.prototype = new Person()
// Implement the subclass constructor's own methods
Children.prototype.sayAge = function () {
  console.log(this.age)
}

const child1 = new Children('Old times'.25)
child1.color.push('black')
console.log(child1) // Person {name: 'old ', color: ['red', 'yellow', 'black'], age: 25}
child1.sayAge() / / 25
child1.sayName() / / the old time

const child2 = new Children('十一'.22)
console.log(child2) // Person {name: '11 ', color: ['red', 'yellow'], age: 22}
child2.sayAge() / / 22
child2.sayName() / /.
Copy the code

Advantages: Instances of composite inheritance combine the advantages of stereotype chain inheritance and constructor inheritance. Instances can have their own attributes and share methods, which is the most commonly used inheritance pattern in JavaScript

4. Prototype inheritance

function createObj(o) {
    function F(){}
    F.prototype = o;
    return new F();
}
Copy the code

Create is a mock implementation of ES5 Object.create that uses the passed Object as a prototype for the created Object. Disadvantages: Attribute values containing reference types always share corresponding values, as with stereotype chain inheritance.

var person = {
    name: 'kevin'.friends: ['daisy'.'kelly']}var person1 = createObj(person);
var person2 = createObj(person);

person1.name = 'person1';
console.log(person2.name); // kevin

person1.firends.push('taylor');
console.log(person2.friends); // ["daisy", "kelly", "taylor"]
Copy the code

Note: Person1. name = ‘person1’; person2.name = ‘person1’; person1.name = ‘person1’; You did not change the name value on the stereotype.

Parasitic inheritance

Create a function that encapsulates inheritance only, internally does enhancement objects in some form, and finally returns objects

function createObj (o) {
    var clone = Object.create(o);
    clone.sayName = function () {
        console.log('hi');
    }
    return clone;
}
Copy the code

Disadvantages: As with the borrowed constructor pattern, methods are created every time an object is created

6. Parasitic combination inheritance

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function prototype(child, parent) {
    var prototype = object(parent.prototype);
    prototype.constructor = child;
    child.prototype = prototype;
}

prototype(Child, Parent);
Copy the code

The efficiency of this approach is that it calls the Parent constructor only once, and thus avoids creating unnecessary, redundant properties on Parent. Prototype. At the same time, the prototype chain stays the same; Therefore, instanceof and isPrototypeOf can also be used normally. Parasitic combinatorial inheritance is generally considered by developers to be the ideal inheritance paradigm for reference types