A good explanation of JavaScript inheritance, but slow to explain now. Don't say much nonsense, go straight to the chase.
Since you want to understand the inheritance, prove that you have a certain understanding of JavaScript object-oriented, such as what is not understood can refer to the "Object-oriented JS basic explanation, Factory mode, constructor mode, prototype mode, mixed mode, dynamic prototype mode", The next step is to complete the JavaScript inheritance through those methods.
Prototype chain
The simplest way to implement inheritance in JavaScript is to use a prototype chain to Point a prototype of a subtype to an instance of the parent type , which is "subtype. prototype = new parent type ();", the implementation method is as follows:
//to create a constructor for a parent typefunctionsupertype () { This. name = [' Wuyuchang ', ' Jack ', ' Tim ']; This. property =true;}//add a method to a parent typeSuperType.prototype.getSuerperValue =function() { return This. property;}//create a constructor for a subtypefunctionsubtype () { This. test = [' H1 ', ' H2 ', ' H3 ', ' H4 ']; This. Subproperty =false;}//A critical step to implement inheritance, where a prototype of a subtype points to an instance of the parent typeSubtype.prototype =Newsupertype ();//To add a method to a subtype here, make sure that after the inheritance is implemented, the pointer will be directed to an instance of the parent type, then the method is emptySubType.prototype.getSubValue =function() { return This. Subproperty;}/*The following is a sample test code*/varInstance1 =Newsubtype (); Instance1.name.push (' WYC '); Instance1.test.push (' H5 '); alert (Instance1.getsuerpervalue ()); //trueAlert (Instance1.getsubvalue ());//falsealert (instance1.name);//WUYUCHANG,JACK,TIM,WYCalert (instance1.test);//H1,h2,h3,h4,h5varInstance2 =Newsubtype (); alert (instance2.name); //WUYUCHANG,JACK,TIM,WYCalert (instance2.test);//H1,h2,h3,h4
You can see that the code above is a simple inheritance through the prototype chain, but there are still some problems in the test code sample. I believe I've read my blog. "Object-oriented JS basic explanation, Factory mode, constructor mode, prototype mode, mixed mode, dynamic prototype mode" Children's shoes must know that the first problem with the prototype chain code is that the prototype of the subtype is an instance of the parent type, that is, the property of the parent type contained in the prototype of the child type. The prototype property that causes the reference type value to be shared by all instances . The Instance1.name.push (' WYC ') of the above code will prove the existence of this problem. The second problem with the prototype chain is that you cannot pass arguments to a super-type constructor When you create an instance of the subtype . So we seldom use the prototype chain alone in actual development.
borrowing Constructors
To solve two problems in the prototype chain, developers began using a technique called borrowing constructors to solve problems in the prototype chain. The implementation of this technique is also quite simple, just call the constructor of the parent type within the constructor of the sub-type. Remember, a function is simply an object that executes code in a particular environment, so you can execute the constructor by using the Apply () or call () method . The code is as follows:
//to create a constructor for a parent typefunctionsupertype (name) { This. Name =name; This. color = [' Pink ', ' yellow ']; This. property =true; This. Testfun =function() {alert (' http://www.cnblogs.com/wuyuchang/'); }}//add a method to a parent typeSuperType.prototype.getSuerperValue =function() { return This. property;}//create a constructor for a subtypefunctionsubtype (name) {Supertype.call ( This, name); This. test = [' H1 ', ' H2 ', ' H3 ', ' H4 ']; This. Subproperty =false;}//To add a method to a subtype here, make sure that after the inheritance is implemented, the pointer will be directed to an instance of the parent type, then the method is emptySubType.prototype.getSubValue =function() { return This. Subproperty;}/*The following is a sample test code*/varInstance1 =NewSubtype ([' Wuyuchang ', ' Jack ', ' Nick ')]); Instance1.name.push (' Hello '); Instance1.test.push (' H5 '); Instance1.color.push (' Blue '); Instance1.testfun (); //http://www.cnblogs.com/wuyuchang/alert (instance1.name);//Wuyuchang,jack,nick,hello//alert (Instance1.getsuerpervalue ()); Error errorsalert (instance1.test);//H1,h2,h3,h4,h5Alert (Instance1.getsubvalue ());//falsealert (Instance1.color);//Pink,yellow,bluevarInstance2 =NewSubtype (' WYC '); Instance2.testfun (); //http://www.cnblogs.com/wuyuchang/alert (instance2.name);//WYC//alert (Instance2.getsuerpervalue ()); Error errorsalert (instance2.test);//H1,h2,h3,h4Alert (Instance2.getsubvalue ());//falsealert (Instance2.color);//Pink,yellow
You can see that the above code is in the constructor of the sub-type subtype by calling the parent type "Supertype.call (this, name);", thus implementing the inheritance of the property, or passing arguments to the parent type when the subtype creates the instance, but the new problem comes again. You can see that I have defined a method in the constructor of the parent type: Testfun, which defines a method in the prototype of the parent type: Getsupervalue. However, after instantiating a subtype, it is still not possible to call the method defined in the prototype of the parent type Getsupervalue, only the method of the constructor in the parent type can be called: Testfun. This is the same as using only the constructor pattern in the Create object, making the function non-reusable. With these problems in mind, the technique of borrowing constructors is seldom used alone.
Combinatorial Inheritance (prototype chain + borrowing constructors)
As the name implies, combinatorial inheritance is a pattern combined with the advantages of using a prototype chain and borrowing a constructor function. Implementation is also very simple, since it is a combination, which of course combines the advantages of the two sides, that is , the prototype chain inheritance method, and in the constructor inheritance properties . The specific code is implemented as follows:
//to create a constructor for a parent typefunctionsupertype (name) { This. Name =name; This. color = [' Pink ', ' yellow ']; This. property =true; This. Testfun =function() {alert (' http://www.cnblogs.com/wuyuchang/'); }}//add a method to a parent typeSuperType.prototype.getSuerperValue =function() { return This. property;}//create a constructor for a subtypefunctionsubtype (name) {Supertype.call ( This, name); This. test = [' H1 ', ' H2 ', ' H3 ', ' H4 ']; This. Subproperty =false;} Subtype.prototype=Newsupertype ();//To add a method to a subtype here, make sure that after the inheritance is implemented, the pointer will be directed to an instance of the parent type, then the method is emptySubType.prototype.getSubValue =function() { return This. Subproperty;}/*The following is a sample test code*/varInstance1 =NewSubtype ([' Wuyuchang ', ' Jack ', ' Nick ')]); Instance1.name.push (' Hello '); Instance1.test.push (' H5 '); Instance1.color.push (' Blue '); Instance1.testfun (); //http://www.cnblogs.com/wuyuchang/alert (instance1.name);//Wuyuchang,jack,nick,helloAlert (Instance1.getsuerpervalue ());//truealert (instance1.test);//H1,h2,h3,h4,h5Alert (Instance1.getsubvalue ());//falsealert (Instance1.color);//Pink,yellow,bluevarInstance2 =NewSubtype (' WYC '); Instance2.testfun (); //http://www.cnblogs.com/wuyuchang/alert (instance2.name);//WYCAlert (Instance2.getsuerpervalue ());//truealert (instance2.test);//H1,h2,h3,h4Alert (Instance2.getsubvalue ());//falsealert (Instance2.color);//Pink,yellow
The above code passes through Supertype.call (this, name), inherits the properties of the parent type, through Subtype.prototype = new Supertype (), and inherits the method of the parent type. The above code is very convenient to solve the prototype chain and borrowing the problems encountered by the constructor, JavaScript is the most common example of the method of inheritance. However, mixed mode is not without drawbacks, you can see in the above code in the inheritance method when the actual inherited property of the parent type, but at this time for the reference type is shared, Therefore, in the constructor of a subtype, calling the constructor of the parent type in order to inherit the property of the parent type overrides the inherited property in the prototype, so it is not necessary to invoke the two constructor, but what can be done to solve it? Look at the following two patterns when solving this problem.
Prototype inheritance
The implementation of the prototype inheritance is different from that of ordinary inheritance, and the prototype inheritance does not use the strict constructor, but the prototype can create the new object based on the existing object without having to create a custom type. The specific code is as follows:
function Object (o) { function F () {} = o; return New F ();}
code example:
/*prototype Inheritance*/functionObject (o) {functionF () {} F.prototype=o; return NewF ();}varperson ={name:' Wuyuchang ', friends: [' Wyc ', ' Nicholas ', ' Tim ']}varAnotherperson =object (person); Anotherperson.name= ' Greg '; AnotherPerson.friends.push (' Bob ');varAnotherPerson2 =object (person); Anotherperson2.name= ' Jack '; AnotherPerson2.friends.push (' Rose '); alert (person.friends); //Wyc,nicholas,tim,bob,rose
Parasitic Inheritance
/** *function createanother (original ) {var clone = Object (original); function () { alert (' Hi '); } return clone;}
Examples of Use:
/*prototype Inheritance*/functionObject (o) {functionF () {} F.prototype=o; return NewF ();} /*Parasitic Inheritance*/functionCreateanother (original) {varClone =object (original); Clone.sayhi=function() {alert (' Hi '); } returnclone;}varperson ={name:' Wuyuchang ', friends: [' Wyc ', ' Nicholas ', ' Rose ']}varAnotherperson =Createanother (person); Anotherperson.sayhi ();
Parasitic combined inheritance
As I said before, the disadvantage of implementing the inheritance in Javascrip is to solve the disadvantage of it, and the realization idea is that, for the constructor inheriting the attribute, and the prototype chain's hybrid form inheriting method, that is, the constructor of the parent type is not instantiated at the time of inheriting the method. The code is as follows:
function object (o) { function F () {} f.prototype = o; return new F ();} /* */ function Inheritprototype (subtype, supertype) { var prototype = object (Supertype.prototype); Prototype.constructor = subtype; Subtype.prototype = prototype;}
In the case of use only the "Subtype.prototype = new Supertype () in the combined mode is required;" This line of code is replaced by Inheritprototype (subtype, supertype); The high efficiency of parasitic combined inheritance is reflected in its invocation of only one parent type constructor, avoiding the creation of unnecessary or superfluous properties. At the same time, the prototype chain remains the same, so instanceof and isprototypeof () can be used normally. This is also the most ideal way of succession, and is now in the transition to this model. (Yui also used this model.) )
This blog post references the 3rd edition of Advanced JavaScript Programming, with the code rewritten, more specific, and annotated to make it easier for everyone to understand. such as the JS inheritance has a unique opinion of the children's shoes do not mean, reply to your opinion for your reference!