JS inheritance borrowing constructor inheritance

Source: Internet
Author: User

First, the shortcomings of the prototype chain 1.1 One of the biggest drawbacks of simple prototype chain inheritance is the erroneous modification of reference type values in the prototype.

Let's look at an example:

//Parent class: Peoplefunction Person () { This. Head ='Head'; }    //Subclass: Student, inherit the category of "man"function Student (studentid) { This. StudentID =StudentID; } Student.prototype=NewPerson (); varSTU1 =NewStudent (1001); Console.log (Stu1.head); //HeadStu1.head='Smart head melon seeds'; Console.log (Stu1.head); //Smart head melon seeds        varSTU2 =NewStudent (1002); Console.log (Stu2.head); //Head

In the above example, we implement the Student class's inheritance of the person class by overriding the value of Student.prototype as an instance of the person class. Therefore, STU1 can access the Head property defined on the parent class person, and the print value is "head". We know that all Student instances share properties on the prototype object. So, if I change the value of the Head property on the STU1, does it affect the head value on the prototype object? Look at the code above and I know it's definitely not. The head value of STU1 is indeed changed, but the head value of the object STU2 I re-instantiated is still the same.

This is because when an attribute with the same name on the prototype object exists in the instance, the property with the same name on the prototype object is automatically masked . Stu1.head = "Clever head melon" actually just adds a local property head to STU1 and sets the relevant value. So when we print stu1.head, we access the local property of the instance, not the head property on its prototype object (it has been masked by the same name as the local property name).

The Head property we discussed just now is a basic type of value, but what if it is a reference type? This one will have a bunch of little 99.

In fact, any type of value on the prototype object will not be overridden/overwritten by the instance. Setting the value of a property on the instance with the same name on the prototype object will only create a local property with the same name on the instance.

However, the value of the reference type on the prototype object can be modified by the instance, causing the value of the reference type shared by all instances to change as well.

Let's look at the following example:

//Parent class: Peoplefunction Person () { This. Head ='Head';  This. Emotion = ['Hi','Anger','Grief','le'];//all people have emotions.    }    //Subclass: Student, inherit the category of "man"function Student (studentid) { This. StudentID =StudentID; } Student.prototype=NewPerson (); varSTU1 =NewStudent (1001); Console.log (stu1.emotion); //[' Hi ', ' anger ', ' grief ', ' le ']Stu1.emotion.push ('Sorrow'); Console.log (stu1.emotion); //["Hi", "anger", "sorrow", "Joy", "Sorrow")        varSTU2 =NewStudent (1002); Console.log (stu2.emotion); //["Hi", "anger", "sorrow", "Joy", "Sorrow")

We have added a emotion sentiment attribute in the person class just now, people all have the emotions. It is especially important to note that this is a value of a reference type. At this time, stu1 think he is still very "worried", so through the Stu1.emotion.push () method in the original on the basis of an increase in an emotion, ah, print out "sadness sorrow", no problem. But Stu2 is an optimist, he why also follow together sorrow?! It must be wrong.

This is the disadvantage of simple prototype chain inheritance, and if one instance accidentally modifies the value of a reference type on the prototype object, it causes the other instances to be affected as well.

  Therefore, we conclude that any type of attribute value on the prototype is not overridden by an instance, but that the value of the reference type's property is modified by the instance's influence.

1.2The prototype chain cannot implement a subclass to pass parameters to the parent class. There is no detail here. Second, the implementation principle of borrowing the constructor 2.1

In the process of solving the problem of containing reference type values in the prototype object, the developer began using a technique called borrowing constructors . The implementation principle is that, in the constructor of the subclass, the parent class constructor is invoked in the form of apply () or call () to implement inheritance.

//Parent class: Peoplefunction Person () { This. Head ='Head';  This. Emotion = ['Hi','Anger','Grief','le'];//all people have emotions.    }    //Subclass: Student, inherit the category of "man"function Student (studentid) { This. StudentID =StudentID; Person.call ( This); }        //student.prototype = new Person ();    varSTU1 =NewStudent (1001); Console.log (stu1.emotion); //[' Hi ', ' anger ', ' grief ', ' le ']Stu1.emotion.push ('Sorrow'); Console.log (stu1.emotion); //["Hi", "anger", "sorrow", "Joy", "Sorrow")        varSTU2 =NewStudent (1002); Console.log (stu2.emotion); //["Hi", "anger", "sorrow", "le")

The attentive classmate may have discovered that this example is very similar to the example above, except that it removes the previous method of inheriting through prototype, and implements inheritance in the form of Person.call (this). Don't forget, the function is just a special object that can execute code at a specific scope, and we can specify the scope of the function through the call method.

(digression: Maybe some students are not fully aware of this point, I understand that: who calls it, it points to who.) )

In the STU1 = new Student () constructor, the STU1 calls the Student method, so its internal this value points to stu1, so Person.call (this) is equivalent to person.ca LL ( stu1 ), is equivalent to STU1. Person (). Finally, when STU1 calls the person method, the this point inside the person points to stu1. All the properties and methods on this inside the person are copied to the STU1. STU2 is also the same, so in fact, each instance has its own copy of the Emotion property. They don't affect each other. Speaking of which, we should know a little bit.

In summary, in a subclass function, after calling the parent class function through the call () method, the subclass instance is STU1 and can access all the properties and methods in the Student constructor and the person constructor. This enables the child class to inherit from the parent class, and also resolves the false modification of the reference type value on the prototype object.

2.2 Disadvantages

In this form of inheritance, each subclass instance copies a copy of the method in the parent class constructor as an instance of its own method, such as Eat (). To do so, there are several drawbacks:

1. Each instance is copied one copy, the memory is large, especially when the method is too high. (function reuse is not discussed, we used prototype is to solve the problem of multiplexing)

2. Methods are used as examples of their own methods, when the requirements change, to change one of the methods, all previous instances, their methods can not be updated in a timely manner. Only the later instances can access the new method.

//Parent class: Peoplefunction Person () { This. Head ='Head';  This. Emotion = ['Hi','Anger','Grief','le'];//all people have emotions.       This. Eat =function () {Console.log (' Eat'); }       This. Sleep =function () {Console.log ('Sleep'); }       This. Run =function () {Console.log ('Run'); }    }

Therefore, whether to use the prototype chain alone or to borrow constructor inheritance has its own great shortcomings, the best way is to combine the two together to play their respective advantages

Reference http://www.cnblogs.com/sarahwang/p/6879161.html

JS inheritance borrowing constructor inheritance

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.