Deep understanding of the JavaScript series (45): Code reuse Mode (avoid the chapter) detailed Knowledge _ Basics

Source: Internet
Author: User
Tags hasownproperty

Introduced

Any programming uses code reuse, otherwise every time you develop a new program or write a new feature, you need to write new words, that's a good break, but the code reuse is also bad, the next two articles we will discuss the code reuse, the first article avoids the article, refers to try to avoid using these patterns, Because more or less has brought some problems; the second row is recommended, refers to the recommended mode of use, generally will not have any problems.

Mode 1: Default mode

Code reuse common default mode, which is often problematic, creates an object using the constructor of parent () and assigns the object to the prototype of the child (). Let's take a look at the code:

Copy Code code as follows:

function inherit (C, P) {
C.prototype = new P ();
}

Parent constructor
function Parent (name) {
this.name = Name | | ' Adam ';
}
Adding say functionality to prototypes
Parent.prototype.say = function () {
return this.name;
};
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: cannot allow arguments to be passed to the child constructor
var s = new Child (' Seth ');
Console.log (S.say ()); "Adam"


The disadvantage of this model is that the child cannot be passed into the parameters and is basically obsolete.

Mode 2: Borrowing constructors

The pattern is that the child uses the constructor of parent to apply, and then passes the this and parameters of the child to the Apply method:

Copy Code code as follows:

Parent constructor
function Parent (name) {
this.name = Name | | ' Adam ';
}

Adding say functionality to prototypes
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, say method is not available, because did not inherit over.

Mode 3: Borrow the constructor and set the prototype

Both of these models have their own shortcomings, then how to remove the shortcomings of both, we try to:

Copy Code code as follows:

Parent constructor
function Parent (name) {
this.name = Name | | ' Adam ';
}

Adding say functionality to prototypes
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"


It worked, everything was fine, but there was no discovery that the parent constructor was executed two times, so that although the program was available, it was inefficient.

Mode 4: Shared prototypes

Shared prototypes refer to the same prototype used by the child and parent, as follows:

Copy Code code as follows:

function inherit (C, P) {
C.prototype = P.prototype;
}

Parent constructor
function Parent (name) {
this.name = Name | | ' Adam ';
}

Adding say functionality to prototypes
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);


To be sure, the child's parameters are not properly received.

Mode 5: Temporary constructors

The constructor is first borrowed, then the child's prototype is set to an instance of the borrowed constructor, and finally the constructor of the child prototype is restored. The code is as follows:

Copy Code code as follows:

/* Closures/* *
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 ';
}

Adding say functionality to prototypes
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


As usual, the child does not receive parameters correctly.

Mode 6:klass

This mode, first the code bar:

Copy Code code as follows:

var klass = function (Parent, props) {

var child, F, I;

   //1.
   //New constructor
    child = function () {
      & nbsp 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.
Inherited
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 to child;
};

var man = Klass (null, {
__construct:function (what) {
Console.log ("Man ' s constructor");
THIS.name = what;
},
Getname:function () {
return this.name;
}
});

var-i = 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 Mans); True
Console.log (Clark instanceof Superman); True


What do you think? Look is not a little dizzy, say, the pattern of syntax and specification twist and other languages, you are willing to use it? Cough...

Summarize

Although the above six modes have implemented some functions under some special circumstances, they all have their own disadvantages, so we should avoid using them in general.

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.