The whole is divided into four categories: using empty objects as mediation inheritance, object.create inheritance, setprototypeof inheritance, copy inheritance
function Animal (name, age) { this. Name = name; this. Age == { function() { Console.log (this . name);} } function Cat () { animal.apply (this, arguments); this. Food = ' mouse ';}
I. Using an empty object as an intermediary inheritance
function Extend (child, parent) { varfunction() {}; = Parent.prototype; New F (); = Child ;}
F is an empty object, so it hardly accounts for memory. This is actually the way YUI implements inheritance.
Give it a try.
Ii. Succession of Object.create
Object.create uses the specified prototype object and properties to create a new object.
function Extend (child, parent) { // Any prototype object has a constructor property that points to its constructor. // make Cat.prototype point to Animal.prototype, but he has a side effect: Cat.prototype.constructor points to Animal Child.prototype = object.create (parent.prototype); // Fix Constructor Child.prototype.constructor = Child ;}
Give it a try.
Question one: Why not direct child.prototype = Parent.prototype; ?
If this is the case,Child.prototype will directly refer to the Parent.prototype object, so when you assign a value to the Child.prototype.constructor, Parent.prototype.constructor also changed the
Question two: why not Child.prototype = new parent (); ?
New parent () does create an object that is associated to the Child.prototype. However, if the function parent has some side effects (such as modifying the state, registering to other objects, adding attributes to this, etc.), it will affect the descendants of child (), and the consequences are unimaginable!
In full, object.create is the best choice, although it is creating a new object that replaces the default object. Is there a way to modify the default object directly? The answer is setprototypeof.
Iii. Succession of setprototypeof
Setprototypeof is a new helper function for ES6. Here's a comparison.
// Discard the default child.prototypeChild.prototype = object.create (parent.prototype); // Modify the default Child.prototype directly Object.setprototypeof (Child.prototype, Parent.prototype);
By comparison, if you ignore the slight loss of object.create () (Discarded objects need to be garbage collected), it is more readable than the ES6 method.
Iv. Copy Inheritance
is also the way that JQuery implements inheritance
//Copy InheritancefunctionExtend () {varoptions, SRC, copy, Copyisarray, clone, Target= Arguments[0] | |{}, deep=false, I= 1; if(typeoftarget = = = ' Boolean ') { deep=Target; Target= Arguments[i] | | {}; I++; } if(typeofTarget!== ' object ' &&!Isfun (target)) {Target= {}; } //loop one or more objects to be copied for(; i<arguments.length; i++ ) { if(options = Arguments[i])! =NULL ) { for(Nameinchoptions) {src=Target[name]; Copy=Options[name]; //prevent the cycle of death if(target = = =copy) { Continue; } Copyisarray=IsArray (copy); if(Deep && copy && isplainobject (copy) | |Copyisarray)) { //Deep Copy if(Copyisarray) {Copyisarray=false; Clone= src && isarray (src)?src: []; } Else{Clone= src && isplainobject (src)?src: {}; } Target[name]=extend (deep, clone, copy); //Prevent copy undefined}Else if(Copy!==undefined) {Target[name]=copy; } } } } returnTarget;}functionIsfun (obj) {returnType (obj) = = = ' [Object Function] ';}functionIsplainobject (obj) {returnType (obj) = = = ' [Object Object] ';}functionIsArray (obj) {//IE8 not supported if(Array.isarray) {returnArray.isarray (obj); } Else { returnType (obj) = = = ' [Object Array] '; }}functiontype (obj) {if(obj = =NULL ) { //obj + ' = ' null '/' undefined ' return false; } returnObject.prototype.toString.call (obj);}varObject1 ={apple:0, Banana: {weight:PRICE:100, }};varObject2 ={banana: {price:200}, Cherry:97};extend (true, Object1, Object2);
Give it a try.
Decoding JS (prototype) inheritance