Deep understanding of JavaScript series (45): code reuse mode (avoid)

Source: Internet
Author: User
Tags hasownproperty
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

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.