Inheritance is the front-end interview must ask, when it comes to inheritance, we must talk about the prototype chain.

Prototype chain

Var a={} or var a= new Object() or use the constructor form: Var a = new a () When an Object is created, it not only has access to its own attributes, but also finds attributes on its prototype chain based on the __proto__ attribute until it finds null on Object. If it is not appropriate, please comment on it. Refer to MDN for more details: developer.mozilla.org/zh-CN/docs/…

For the following example:

var A = function(){
    this.name="xiaoming"; } A.prototype.age=9; var a = new A(); console.log(a.age); / / 9Copy the code

I refer to the drawing of instance and Class of Java in the past to draw a prototype chain. It is not good, but it is not easy to draw the drawing.

a.__proto__ === A.prototype; //true
A.prototype.constructor===A; //true
A.prototype.__proto__===Object.prototype; //true
Object.prototype.__proto__===null; //true
Copy the code

The above example can be reviewed after I have explained it. Instance and prototype are connected by __proto__ attribute, and is one-way, from the instance to the prototype; The connection between the prototype and the constructor is bidirectional, via constructor and Prototype, as shown in the figure. Properties on the prototype chain are shared by all instances, as shown in the following example:

var A = function(){
    this.name="xiaoming"; } var a = new A(); A.prototype.age=9; var b = new A(); console.log(a.age); //9 console.log(b.age); / / 9Copy the code

Both A and B can access the property age on a’s prototype chain.

Function and Object are special. They are both objects and functions. They contain both proto and prototype attributes.

Object.__proto__ === Function.prototype //true
Object.__proto__ === Function.__proto__//true
Object.prototype === Function.prototype.__proto__ // true
Function instanceof Object //true
Object instanceof Function //true
Copy the code

At this point, the knowledge of the prototype chain is more or less understandable, and there are several ways to inheritance.

Prototype chain inheritance

Now that you have access to all of the properties of the stereotype chain, you can implement inheritance using the principles of the stereotype chain. Prototype chain inheritance with new (implement A inherit B) : a.protoType =new B(); For new, you can read my other article “this” and other things.

Code:

function B(){
    this.nameB='B';
}
B.prototype.nameProto="PROTO";
function A(){
    this.nameA="A"; } A.prototype=new B(); Var A =new A(); console.log(a);Copy the code

Print result:

Example A with A constructor new inherits not only B (nameB accessible), but also properties on the B stereotype (nameProto) that are shared by all instances.

Benefits: You can inherit the properties of the prototype chain. Disadvantages: Multiple inheritance cannot be realized. If A inherits B, it cannot inherit C.

Tectonic inheritance

Constructor inheritance uses constructor inheritance, that is, call/apply/bind the way this points to B once. Without further ado, examples:

function B(){
    this.nameB='B';
}
B.prototype.nameProto="PROTO";
function A(){ B.call(this); //A extends to B.bindSimilar to this. NameA ="A";
}
var a=new A();
console.log(a);
Copy the code

Print result:

The attribute nameProto on the B prototype chain could not be inherited
Multiple inheritance
C.call(this)

Benefits: Can inherit more. Disadvantages: Inability to inherit properties on the prototype chain.

Combination of inheritance

Combinatorial inheritance is born to solve the problem that the prototype chain inheritance cannot inherit multiple inheritance and the construction inheritance cannot inherit the attributes on the prototype chain.

function B(){
    this.nameB='B';
}
B.prototype.nameProto="PROTO";
function A(){ B.call(this); // Construct inherits this.namea ="A"; } A.prototype=new B(); Var A =new A(); console.log(a);Copy the code

Print result:

There are two nameB attributes

Primary inheritance

Take a look at the following example:

function objectCreate(obj){
  function F() {}; F.prototype = obj;return new F();
}
var a=objectCreate(A.prototype);
Copy the code

In the last example,

  1. use__proto__:A.prototype.__proto__=B.prototype
  2. useObject.create:A.prototype=Object.create(B.prototype)