Front-end students should be familiar with the little Red Book advanced programming, which can be called a must-read classic for front-end personnel. It is also the first book I bought in the industry. Now to summarize a few things about object prototype chain inheritance

1. Create an object

  • 1) Factory model

function creat(name,age){
    var obj = new Object()
    obj.name = name
    obj.age = age
    obj.getAge = function(){
        console.log(this.age)
    }
    return obj
}

var studentA = creat('xiaohong'.18)
studentA.getAge() / / 18
console.log(studentA.name) // xiaohong
Copy the code

Each call to creat returns an object that contains the name age attribute and a getAge method. Disadvantages: Does not solve the object identification problem

  • 2) Constructor pattern

function Creat(name,age){
    this.name = name
    this.age = age
    this.getAge = function(){
        console.log(this.age)
    }
}

var studentA = new Creat('xiaohong'.18)
studentA.getAge() / / 18
console.log(studentA.name) // xiaohong
Copy the code

To create an instance of a constructor, you must use the keyword new operator. You can focus on that

Create a new object

B. Assign constructor scope to new object (modify this pointer)

C. Execute constructor (add object and method for new object)

D. Return a new object

StudentA is an example of Creat,

This instance contains a constructor property that points to Creat.

This instance contains a constructor property that points to Creat.

This instance contains a constructor property that points to Creat.

console.log(studentA.constructor == Creat) //true
Copy the code

The instanceof operator checks that the Object type studentA is both an instanceof Creat and an instanceof Object

console.log(studentA instanceof Creat) //true
console.log(studentA instanceof Object) //true
Copy the code

Constructor problems each method is created on each instance. The solution

function Creat(name,age){
    this.name = name
    this.age = age
    this.getAge = getAge
}

function getAge (){
    console.log(this.age)
}
Copy the code

Each instance shares methods in the global object, but defining multiple methods requires defining many global functions

3) Prototype mode

function Person(){}
Person.prototype.age = '18'
Person.prototype.name = 'xiaohong'
Person.prototype.getAge = function(){
    console.log(this.age)
}
var studentA = new Person()
studentA.getAge() / / 18
Copy the code

Whenever a function is created, the function’s prototype property points to the function’s prototype object. All prototype objects get a constructor property that contains a pointer to the function of the Prototype property

If a new property added to the instance has the same name as the property on the stereotype, the property on the stereotype is masked (only masked without modification)

function Person(){}
Person.prototype.age = '18'
Person.prototype.name = 'xiaohong'
Person.prototype.getAge = function(){
    console.log(this.age)
}
var studentA = new Person()
studentA.name='lucy'
console.log(studentA.hasOwnProperty('name')) //true
console.log('name' in studentA) //true
console.log('job' in studentA)  //false
Copy the code

The hasOwnProperty() method determines whether the property is from an instance or a stereotype

The in operator returns true for any property accessible through the object

So hasOwnProperty() and in determine whether the property is from a stereotype or an instance

Disadvantages: All instances have the same properties and methods by default if the instance modifies the property values of the prototype object the other instances are also modified

4) Use constructors and stereotype patterns in combination

The most common way to create custom types is to use constructors to create properties, and the stereotype pattern defines methods and shared properties

function Person(name,age){
    this.name = name
    this.age = age
}
Person.prototype={
    construtor:Person,
    getAge:function(){
        console.log(this.age)
    }
}
var studentA = new Person()
studentA.name='lucy'
console.log(studentA.name) //lucy
Copy the code

5) Parasitic constructors

This pattern is actually the same as the factory pattern. But you can’t use instanceof to define a type, so you generally don’t use this pattern.

function Person(name,age){
    var o = new Object()
    o.name = name;
    o.age = age;
    o.sayAge = function(){
        console.log(this.age)
    }
    return o
}
var studentA = new Person('lucy'.'18')
studentA.sayAge()/ / 18
Copy the code

2. The prototype chain

  • Prototype chain – is the primary method of implementing inheritance

Use stereotype objects to make one reference type inherit the properties and methods of another

function Father(){
    this.property=true
}
Father.prototype.sayFatherName = function(){
    return this.property
}

function Child(){
    this.subproperty=false
}
Child.prototype = new Father()
Child.prototype.sayChildName = function(){
    return this.subproperty
}
var child1 = new Child()
console.log(child1.sayFatherName()) //true
Copy the code

Note: The subtype addition method comes after the replacement type

Adding methods to subclasses cannot use literals!! This will invalidate inheritance!!

The inheritance of the prototype practice is by creating an instance of Father

Instanceof determines the relationship between stereotypes and instances

console.log(child1 instanceof Child ) //true
console.log(child1 instanceof Father ) //true
console.log(child1 instanceof Object ) //true
Copy the code
  • The borrow constructor inherits call Apply

function Father(){
    this.color=['red'.'green']}function Child(){
    Father.call(this)}var child1 = new Child()
var child2 = new Child()
child1.color.push('blue')
console.log('child1:',child1.color) //[ 'red', 'green', 'blue' ]
console.log('child2:',child2.color) //[ 'red', 'green' ]
Copy the code

Disadvantages: Methods are defined in constructors and cannot be reused

  • Combination of inheritance

function Father(name,age){
    this.name = name
}
Father.prototype.sayName = function(){
    console.log(this.name)
}

function Child(name,age){
    Father.call(this,name) // call Father the second time
    this.age = age
}
Child.prototype = new Father() // call Father for the first time
Child.prototype.constructor = Child
Child.prototype.sayAge = function(){
    console.log(this.age)
}

var child1 = new Child('Lucy'.'18')
child1.sayName()//Lucy
child1.sayAge()/ / 18
Copy the code

Composite inheritance, which avoids the disadvantages of stereotype chain and constructor inheritance, is the most common inheritance pattern

  • Parasitic combinatorial inheritance

function inheritPrototype(subtype,supertype){
    var prototype = Object(supertype.prototype) // Create an object
    prototype.constructor = subtype // Enhance objects
    subtype.prototype = prototype  // Specify the object

}

function Father(name,age){
    this.name = name
}
Father.prototype.sayName = function(){
    console.log(this.name)
}

function Child(name,age){
    Father.call(this,name)
    this.age = age
}
inheritPrototype(Child,Father)

Child.prototype.sayAge = function(){
    console.log(this.age)
}

var child1 = new Child('Lucy'.'18')
child1.sayName()//Lucy
child1.sayAge()/ / 18
Copy the code
conclusion

Inheritance is implemented primarily through prototype chains in JavaScript.

The chain of stereotypes is built by assigning a type instance to the stereotype of another constructor.

The most commonly used method of inheritance is composite inheritance, where instance properties are inherited through constructors and shared properties and methods are inherited using stereotype chains.