JavaScript code reuse mode (ii)

Source: Internet
Author: User
Tags hasownproperty

As mentioned earlier, the code reuse pattern of JavaScript can be divided into class-type inheritance and non-class inheritance (modern Inheritance). This article continues the class-type inheritance.

Class inheritance mode-borrowing constructors

Using a method borrowed from a constructor, you can get the parent constructor to pass any number of arguments from the child constructor. This pattern borrows the parent constructor, which passes the child object to bind to this and forwards any number of arguments:

function Child (a,b,c,d) {    parent.apply (this,arguments);}

In this way, only the attributes added to this in the parent constructor can be inherited, and members that are added to the prototype cannot be inherited.

When constructing a pattern using a borrowing function, the child object obtains a copy of the inherited member, which is different from the only way to get references in the default stereotype inheritance. You can refer to the following example:

Funciton article () { This. tags = [' js ', ' CSS '];}varArticle =Newarticle ();functionblogpost () {}blogpost.prototype=article;varBlog =Newblogpost ();functionStaticpage () {Article.call ( This);}varpage =Newstaticpage (); Console.log (Article.hasownproperty (' tags '));//trueConsole.log (Blog.hasownproperty (' tags '));//falseConsole,log (Page.hasownproperty (' tags '));//true

The above in two ways inherit article (), the default prototype mode causes the blog object through the prototype to obtain his access to the Tags property, so the blog object does not have article as its own property, so when the call hasOwnProperty () Returns False when the Page object itself has a tags property because when he calls the parent constructor, the new object gets a copy of the tags member in the parent object, not the reference.
You can see the difference in the following code:

Blog.tags.push (' HTML ');p age.tag.push (' php '); Console.log (Article.tags.join (', ')); // "Js,css,html"

In the above code, the sub-object blog modifies its Tags property, and this way also modifies the parent object article, because essentially blog.tags and article.tags point to the same array, but modifying the page's tags does not affect the parent object article, is due to the fact that Page.tags is a separate replica created during the inheritance process.
About the workflow of the prototype chain:

functionParent (name) { This. Name = name| | " Adam ";} Parent.prototype.say= {    return  This. Name;};functionChild (name) {parent.apply ( This, arguments);}varKid =NewChild ("Patrick"); Console.log (kid.name);//"Patric"Console.log (typeofKid.say);//undefined

The above code does not use Child.prototype, it just points to an empty object, when borrowing the parent constructor, kid obtains its own property name, has not inherited the say () method. Inheritance is done once, and only the properties of the parent object are copied and used as their own properties, so the _proto_ link is not preserved.


When you use the borrow constructor, you can implement multiple inheritance by borrowing multiple constructors:

functionCat () { This. Legs = 4;  This. Say =function(){        return"Meaowww"; };}functionBird () { This. Wings = 2;  This. Fly =true;}functioncatwings () {cat.apply ( This); Bird.apply ( This);}varJane =Newcatwings (); Console.dir (Jane);

Operation Result:

    Fly        true    legs       4    wings      2    say          function()

The disadvantage of borrowing a constructor is that it is obvious that you cannot inherit any properties and methods from the prototype, such as the parent and child examples above. Multiple replicas are also created for the method defined with this on the parent constructor. The advantage can obtain a true copy of the parent object's own member, there is no risk that child objects overwrite the parent object, can pass parameters, can be multiple inheritance.

Class inheritance mode-borrowing and setting up prototypes

This pattern is a combination of the first two, the constructor is borrowed, and the prototype of the child constructor is set to point to an instance created by a constructor. The code is as follows:

function Child (a,b,c,d) {    parent.apply (thisnew Parent ();

The advantage of this is that the resulting object after the code runs can get a copy of the member of the parent object itself, as well as point to the reusable functionality in the parent object (which is implemented as a prototype), and the child object can also pass arbitrary arguments to the parent constructor.
This is the closest way to Java or C # implementations. You can inherit everything from the parent object, and you can safely modify its properties without risking the modification of the parent object.

The disadvantage is that the parent constructor is called two times, which leads to inefficiency and its own properties are inherited two times, as in the following name:

functionParent (name) { This. Name = name| | " Adam ";} Parent.prototype.say= {    return  This. Name;};functionChild (name) {parent.apply ( This, arguments);} Child.prototype=NewParent ();varKid =NewChild ("Patrick"); kid.name;//"Patrick"Kid.say ();//"Patrick"DeleteKid.name;kid.say ();//"Adam"

In the code above. Say () was inherited. As you can see, the Name property has been inherited two times, and after you delete the copy of the Name property of the kid itself, you can see that the output is the name derived from the prototype chain.
Prototype chain:

Class inheritance mode-shared prototypes

The following pattern does not involve calling the parent constructor, unlike the previous pattern, which calls for a two-time parent constructor function.

The law of this pattern is that reusable members should be transferred to the prototype instead of in this, so that any property and method that needs to be inherited should be placed in the prototype for the purposes of inheritance, so that only the prototype of the child object and the parent object are set to the same. The code is as follows:

function inherit (c,p) {    = p.prototype;}

This pattern provides a short and fast prototype chain query because all objects actually share a prototype. But this is also a disadvantage, because if you modify the prototype in a sub-object that exists somewhere below the inheritance chain, he affects all parent and ancestor objects.
For example, the following sub-object and parent object share the same prototype and have equal access to the Say () method, but the child object does not inherit the Name property.

JavaScript code reuse mode (ii)

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.