Introduction
Any ProgrammingCodeReuse. Otherwise, a newProgramOr if you want to write a new function, you can take a break, but code reuse is also good or bad. The next two articlesArticleWe will discuss code reuse. The first article avoids the article, which means we should avoid using these models as much as possible, because there are more or less problems. The second row is the recommendation article, it refers to the recommended mode, which is generally not a problem.
Mode 1: Default Mode
Code reuse is a common default mode, which is often problematic. This mode uses the parent () constructor to create an object and assign the object to the child () prototype. Let's take a look at the Code:
Function Inherit (C, p ){
C. Prototype = New P ();
}
// Parent Constructor
Function Parent (name ){
This . Name = Name | 'Adam ';
}
// Add the say function to the prototype
Parent. Prototype. Say = Function (){
Return This . Name;
};
// The child constructor is empty.
Function Child (name ){
}
// Execute inheritance
Inherit (child, parent );
VaR KID = New Child ();
Console. Log (kid. Say ()); // "Adam"
VaR Kiddo = New Child ();
Kiddo. Name = "Patrick ";
Console. Log (kiddo. Say ()); // "Patrick"
// Disadvantage: The parameter cannot be passed to the Child constructor.
VaR S = New Child ('seth ');
Console. Log (S. Say ()); // "Adam"
The disadvantage of this mode is that the child cannot pass in the parameter, and it is basically useless.
Mode 2: Borrow Constructor
In this mode, child uses the constructor of parent to apply, and then passes this and parameters of child to the apply method:
// Parent Constructor
Function Parent (name ){
This . Name = Name | 'Adam ';
}
// Add the say function to the prototype
Parent. Prototype. Say = Function (){
Return This . Name;
};
// Child Constructor
Function Child (name ){
Parent. Apply ( This , Arguments );
}
VaR KID = New Child ("Patrick ");
Console. Log (kid. Name ); // "Patrick"
// Disadvantage: The say method is not inherited from the constructor.
Console. Log ( Typeof Kid. Say );// "Undefined"
The disadvantage is also obvious. The say method is not available because it is not inherited.
Mode 3: Borrow the constructor and set the prototype
The above two models both have their own shortcomings. How can we remove the disadvantages of the two models? Let's try:
// Parent Constructor
Function Parent (name ){
This . Name = Name | 'Adam ';
}
// Add the say function to the prototype
Parent. Prototype. Say = Function (){
Return This . Name;
};
// Child Constructor
Function Child (name ){
Parent. Apply ( This , Arguments );
}
Child. Prototype = New Parent ();
VaR KID = New Child ("Patrick ");
Console. Log (kid. Name ); // "Patrick"
Console. Log ( Typeof Kid. Say ); // Function
Console. Log (kid. Say ()); // Patrick
Console. dir (kid );
Delete Kid. Name;
Console. Log (kid. Say ()); // "Adam"
Everything works normally, but have you found that the parent constructor has been executed twice, so although the program is available, the efficiency is very low.
Mode 4: Shared prototype
A shared prototype means that child and parent use the same prototype. The Code is as follows:
Function Inherit (C, p ){
C. Prototype = P. Prototype;
}
// Parent Constructor
Function Parent (name ){
This . Name = Name | 'Adam ';
}
// Add the say function to the prototype
Parent. Prototype. Say = Function (){
Return This . Name;
};
// Child Constructor
Function Child (name ){
}
Inherit (child, parent );
VaR KID = New Child ('Patrick ');
Console. Log (kid. Name ); // Undefined
Console. Log ( Typeof Kid. Say ); // Function
Kid. Name = 'Patrick ';
Console. Log (kid. Say ()); // Patrick
Console. dir (kid );
The child parameter is not correctly received.
Mode 5: Temporary Constructor
First, borrow the constructor, set the child prototype to the instance of the borrow constructor, and then restore the constructor of the Child prototype. The Code is as follows:
/* Closure */
VaR Inherit = ( Function (){
VaR F = Function (){
};
Return Function (C, p ){
F. Prototype = P. Prototype;
C. Prototype = New F ();
C. Uber = P. Prototype;
C. Prototype. constructor = C;
}
}());
Function Parent (name ){
This . Name = Name | 'Adam ';
}
// Add the say function to the prototype
Parent. Prototype. Say = Function (){
Return This . Name;
};
// Child Constructor
Function Child (name ){
}
Inherit (child, parent );
VaR KID = New Child ();
Console. Log (kid. Name ); // Undefined
Console. Log ( Typeof Kid. Say ); // Function
Kid. Name = 'Patrick ';
Console. Log (kid. Say ()); // Patrick
VaR Kid2 = New Child ("Tom ");
Console. Log (kid. Say ());
Console. Log (kid. constructor. Name ); // Child
Console. Log (kid. constructor === parent ); // False
If the problem persists, child cannot receive parameters normally.
Mode 6: Klass
In this mode, go to the code first:
VaR Klass = Function (Parent, props ){
VaR Child, F, I;
// 1.
// New Constructor
Child = Function (){
If (Child. Uber & Child. Uber. hasownproperty ("_ construct ")){
Child. Uber. _ construct. Apply ( This , Arguments );
}
If (Child. Prototype. hasownproperty ("_ construct ")){
Child. Prototype. _ construct. Apply ( This , Arguments );
}
};
// 2.
// Inheritance
Parent = parent | object;
F = Function (){
};
F. Prototype = parent. Prototype;
Child. Prototype = New F ();
Child. Uber = parent. Prototype;
Child. Prototype. constructor = child;
// 3.
// Add Implementation Method
For (I In Props ){
If (Props. hasownproperty (I )){
Child. Prototype [I] = props [I];
}
}
// Return the "class"
Return Child;
};
VaR Man = Klass ( Null ,{
_ Construct:Function (What ){
Console. Log ("Man's constructor ");
This . Name = what;
},
Getname: Function (){
Return This . Name;
}
});
VaR First = New MAN ('Adam '); // Logs "Man's constructor"
First. getname (); // "Adam"
VaR Superman = Klass (man ,{
_ Construct: Function (What ){
Console. Log ("Superman's constructor ");
},
Getname: Function (){
VaR Name = Superman. Uber. getname. Call ( This );
Return "I am" + name;
}
});
VaR Clark = New Superman ('clark Kent ');
Clark. getname (); // "I am Clark Kent"
Console. Log (Clark Instanceof Man ); // True
Console. Log (Clark Instanceof Superman ); // True
How is it? Is it a bit dizzy? Let's say it better. The syntax and norms of this mode are screwed in the same way as other languages. Would you like to use it? Cough...
Summary
Although the above six modes have implemented some functions under certain special circumstances, they all have their own shortcomings. Therefore, we should avoid using them in general.
Reference: http://shichuan.github.com/javascript-patterns/#code-reuse-patterns
Transferred from: Uncle Tom