Determination of the relationship between prototype and instance
- 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
- 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:
- Properties of reference types are shared by all instances
- 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