Since the inheritance of ES6, the inheritance of ES5 has also dropped out of the stage and will not be used in actual development;
Let's take a look at the inheritance of ES6
1 class Father{ 2 3 constructor(a){ 4 console.log(a); 5 } 6 play(){ 7 console.log("aaa"); 8 } 9 static run(){ 10 console.log("static"); 11 } 12 } 13 class Son extends Father{ 14 constructor(){ 15 super(); 16 } 17 } 18 var s=new Son(); 19 s.play(); 20 Father.run() 21 Son.run();
In ES6, you only need to use the extends and super keywords to inherit the methods and properties of the parent class (including static)
There are no keywords in ES5
Inheritance of ES5
There are five ways to inherit ES5:
- Object impersonating inheritance
- Prototype chain inheritance
- Combination inheritance
- Archetypal inheritance
- Parasitic inheritance (important)
- Object impersonating inheritance
1 function Father(_r){ 2 this.r=_r; 3 console.log("aa"); 4 console.log(this.r); 5 } 6 Father.a=3; 7 Father.run=function(){ 8 console.log(Box.a); 9 } 10 function Son(){ 11 Father.call(this,3);//change this Point to, execute the parent constructor and pass a reference to the parent 12 } 13 var b=new Son();//"aa",3 14 b.run();//TypeError
Change this point through call or apply, and execute the constructor of the parent class
Disadvantage: can only inherit the constructor of superclass, can't inherit the method on prototype chain
- Prototype chain inheritance
1 function Father(){ 2 console.log("aa"); 3 } 4 Father.prototype.b=10; 5 Father.prototype.play=function(){ 6 console.log(this.b); 7 } 8 Son.prototype=new Father(); 9 function Son(){ 10 } 11 var b=new Son(); 12 b.play();//10
Assign the instantiated object of the parent class to the inheritance implemented on the prototype of the child class
Disadvantages: override the original properties and methods of the subclass, only the properties and methods of the parent class can be executed, and the constructor of the parent class cannot be executed
- Combination inheritance
The first two kinds of inheritance (impersonation, prototype chain) have their own characteristics. The combination of these two kinds of inheritance is called combination inheritance
1 function Father(_r){ 2 this.r=_r; 3 console.log("aa"); 4 } 5 function Son(_r){ 6 Father.call(this,_r);//To change the parent of this Point to subclass 7 } 8 Son.prototype=new Father(3);//Prototype chain inheritance 9 var c=new Son(10); 10
The prototype chain is used to inherit the properties and methods of the parent class, and the object is used to pretend to inherit the constructor of the parent class
It looks good, but it's not the perfect way to inherit;
Disadvantages: it will override the original properties and methods of the class, because prototype chain inheritance instantiates the parent class and executes the parent class constructor once in advance; when the child class instantiates the object, it actually executes the parent class constructor twice.
Usage scenario: the subclass originally has no properties and methods, and the parent constructor has no content.
- Archetypal inheritance
To solve the problem of executing the parent constructor twice, a mediation is used, and the parent constructor will not be executed when inheriting
1 function Father(_a){ 2 this.a=_a 3 } 4 Father.prototype.play=function(){ 5 console.log("aaa"); 6 } 7 function Agent(){ 8 9 } 10 Agent.prototype=Father.prototype; 11 function Son(){ 12 13 } 14 Son.prototype=new Agent(); 15 var o=new Son(); 16 o.play();//aaa
Using the Agent class as the intermediary, copying the prototype of the parent class, and then instantiating and inheriting will not execute the constructor of the parent class;
Disadvantage: Although the problem of constructor executing twice is solved, the constructor will not execute once after using this method to inherit.
- Parasitic inheritance (perfect inheritance)
Encapsulates an extend method, which passes in two parameters, the parent class and the child class
1 function extend(subClass, supClass) { 2 function Agent() {} 3 Agent.prototype = supClass.prototype; 4 var o = subClass.prototype; 5 subClass.prototype = new Agent(); 6 if (Object.assign) { 7 Object.assign(subClass.prototype, o); 8 } else { 9 if (Object.getOwnPropertyNames) { 10 var names = Object.getOwnPropertyNames(o); 11 for (var i = 0; i < names.length; i++) { 12 var desc = Object.getOwnPropertyDescriptor(names[i]); 13 Object.defineProperty(subClass.prototype, names[i], desc); 14 } 15 } else { 16 for (var prop in o) { 17 subClass.prototype[prop] = o[prop]; 18 } 19 } 20 } 21 subClass.prototype.constructor = subClass; //Prevent subclass constructors from being overridden 22 if (supClass.prototype.constructor === Object) { 23 supClass.prototype.constructor = supClass; //Prevent the constructor of the parent class from being overridden 24 } 25 // Store parent class, convenient to inherit constructor call 26 subClass.prototype.superClass = supClass; 27 } 28 //call 29 function Father(_r) { 30 this.r = _r; 31 console.log("Father"); 32 } 33 Father.prototype.play = function () { 34 console.log("play game"); 35 }; 36 function Ball(_r) { 37 this.superClass.call(this, _r); 38 } 39 40 var s = new Son(10);//Father 41 s.play();//play game
The extend method uses Object.assgin, Object.getOwnPropertyNames, Object.getOwnPropertyDescriptor, and Object.defineProperty, all of which have compatibility problems, so the judgment is made.
This method inherits the advantages of the first four and realizes the perfect inheritance of ES5;
Conclusion:
Compared with the inheritance of ES6, ES5 is too cumbersome to be used in the future;
But when interviewing, the interviewer may ask, it's always right to learn more.