Any programming proposes code reuse. Otherwise, if you need to write a new program every time you develop a new program or write a new function, then it will be a stop. However, code reuse is also good or bad. In the next two articles, we will discuss code reuse. The first article avoids the use of these patterns as much as possible, because it brings some problems to a greater or lesser extent; the second row is the recommendation, which refers to the recommended pattern that everyone uses, and there will generally be no problems.
Mode 1: Default Mode
There is often a problem with code reuse of the default mode commonly used by everyone. This mode uses Parent()'s constructor to create an object and assign the object to the Child() prototype. Let's look at the code:
function inherit(C, P) { = new P();}
// Parent constructor function Parent(name) { = name || 'Adam';}
// Add say function to the prototype = function () { return ;};
// Child constructor is empty function Child(name) {}
// Execute inherit(Child, Parent);var kid = new Child();(());
// "Adam"var kiddo = new Child(); = "Patrick";(());
// "Patrick"// Disadvantages: cannot be passed parameters to the Child constructor var s = new Child('Seth');(());
// The disadvantage of the "Adam" mode is that Child cannot pass parameters, so it is basically useless.
Pattern 2: Borrowing constructor
This pattern is that Child borrows Parent's constructor to apply, and then passes this and parameters of child to the apply method:
// Parent constructor function Parent(name) { = name || 'Adam';}
// Add say function to the prototype = function () { return ;};
// Child constructor function Child(name) { (this, arguments);}var kid = new Child("Patrick");();
// "Patrick"// Disadvantages: The say method (typeof) is not inherited from the constructor;
// The disadvantage of "undefined" is also obvious, and the say method is not available because it has not been inherited.
Pattern 3: Borrow the constructor and set the prototype
The above two modes have their own shortcomings, so how to remove the shortcomings of both? Let’s try:
// Parent constructor function Parent(name) { = name || 'Adam';}// Add say function to the prototype = function () { return ;};// Child constructor function Child(name) { (this, arguments);} = new Parent();var kid = new Child("Patrick");(); // "Patrick"(typeof ); // (kid); delete ;(()); // "Adam" runs and everything is normal, but have you found that the Parent constructor has been executed twice, so although the program is available, it is very inefficient.
Mode 4: Shared Prototype
Shared prototype means that Child and Parent use the same prototype, the code is as follows:
function inherit(C, P) { = ;}
// Parent constructor function Parent(name) { = name || 'Adam';}
// Add say function to the prototype = function () { return ;};
// Child constructor function Child(name) {}inherit(Child, Parent);var kid = new Child('Patrick');();
// (typeof );
// = 'Patrick';(());
// (kid);It is confirmed that the same is true, the Child parameter is not received correctly.
Pattern 5: Temporary constructor
First, borrow the constructor, then set the Child prototype to an instance of the borrowed constructor, and finally restore the constructor of the Child prototype. The code is as follows:
/* Closure */var inherit = (function () { var F = function () { }; return function (C, P) { = ; = new F(); = ; = C; }} ());function Parent(name) { = name || 'Adam';}// Add say function to the prototype = function () { return ;};// Child constructor function Child(name) {}inherit(Child, Parent);var kid = new Child();(); // (typeof ); // = 'Patrick';(()); // Patrickvar kid2 = new Child("Tom");(()); (); // ( === Parent); // The false problem is still the same, Child cannot receive parameters normally.
Mode 6: klass
Let's start with the code for this pattern:
var klass = function (Parent, props) { var Child, F, i; //
1. // New constructor Child = function () { if ( && ("__construct")) { .__construct.apply(this, arguments); } if (("__construct")) { .__construct.apply(this, arguments); } }; //
2. // Inherit ParentParent = Parent || Object; F = function () { }; = ; = new F(); = ; = Child; /
3. // Add implementation method for (i in props) { if ((i)) { [i] = props[i]; } }
// return the "class" return Child;};var Man = klass(null, { __construct: function (what) { ("Man's constructor"); = what; }, getName: function () { return ; }});var first = new Man('Adam');
// logs "Man's constructor"();
// "Adam"var SuperMan = klass(Man, { __construct: function (what) { ("SuperMan's constructor"); }, getName: function () { var name = (this); return "I am " + name; }});var clark = new SuperMan('Clark Kent');();
// "I am Clark Kent"(clark instanceof Man);
// (clark instanceof SuperMan);
Isn't it a little dizzy to see? To be better, the grammar and specification of this pattern are the same as other languages. Are you willing to use it?
Summarize
Although the above six modes implement certain functions in certain special circumstances, they all have their own shortcomings, so in general, everyone should avoid using them.