6 ways to re-understand JS's inheritance

Source: Internet
Author: User

Write in front

Always do not like the JS oop, in the learning phase seems to be used, always think JS oop, may be because the first contact with Java, so the oo part of JS some conflict.

Prejudice biased, since the interviewer asked the JS oop, then this thing is certainly useful, should put aside prejudice, seriously understand

Conventions

P.S. The following will expand a somewhat long story, so it is necessary to agree on a common language in advance:

/* * Convention */function Fun () {    //private attribute    var val = 1;        Private basic attribute    var arr = [1];      Private Reference attribute function Fun    () {}    //Private Function (reference property)    //instance Property    This.val = 1;               Instance Basic properties    This.arr = [1];             Instance Reference Property    This.fun = function () {};    instance function (Reference property)}//prototype attribute Fun.prototype.val = 1;              Prototype Basic Properties Fun.prototype.arr = [1];            Prototype Reference Property Fun.prototype.fun = function () {};   Prototype function (Reference property)

The above agreement should be more reasonable, if difficult to understand, you can view the Breeze: JS Study note 2_ Object-oriented, learn more basic knowledge

I. Simple prototype CHAIN

This is the simplest way to implement inheritance, it's really super simple, the core is a word (in the code with comments marked)

1. Concrete implementation
function Super () {    this.val = 1;    This.arr = [1];} function Sub () {    //...} Sub.prototype = new Super ();    Core var sub1 = new Sub (), var sub2 = new Sub (), Sub1.val = 2;sub1.arr.push (2); alert (sub1.val)    ; 2alert (sub2.val);    1alert (Sub1.arr);    1, 2alert (Sub2.arr);    1, 2
2. Core

Take the parent class instance to act as a subclass prototype object

3. Pros and cons

Advantages:

    1. Simple and easy to implement

Disadvantages:

    1. After modifying Sub1.arr, Sub2.arr also changed because the reference property from the prototype object is shared by all instances.

      It can be understood that: the execution of Sub1.arr.push (2), the first to Sub1 property lookup, found the instance property (in this case no instance attribute), did not find, began to follow the prototype chain up, got the Sub1 prototype object, a search, found the arr attribute. 2 was inserted at the end of Arr, so the Sub2.arr also changed

    2. Cannot pass parameter to parent class when creating child class instance

Two. Borrowing constructors

Simple prototype chain is really simple, but there are 2 fatal shortcomings can not be used, so the last century jsers on the way to fix these 2 defects, and then appeared to borrow a constructor

1. Concrete implementation
Function Super (val) {    this.val = val;    This.arr = [1];    This.fun = function () {        //...    }} Function Sub (val) {    Super.call (this, Val);   Core    //...} var sub1 = new Sub (1), var sub2 = new Sub (2), Sub1.arr.push (2); alert (sub1.val);    1alert (sub2.val);    2alert (Sub1.arr);    1, 2alert (Sub2.arr);    1alert (Sub1.fun = = = Sub2.fun);   False
2. Core

By using the parent class's constructor to enhance the subclass instance , it is equivalent to copying a copy of the parent class's instance property to the subclass instance (no prototype is used at all)

3. Pros and cons

Advantages:

    1. Resolves an issue where subclass instances share parent class reference properties

    2. When you create a subclass instance, you can pass arguments to the parent class constructor

P.S. Seniors are so efficient, two bug fixes instantly

Disadvantages:

    1. Cannot implement function reuse, each child class instance holds a new fun function, too many will affect performance, memory explosion.

P.s. OK, just fixed the issue of shared reference properties, and this new issue arises.

Three. Combination inheritance (most commonly used)

There is still a problem with the way we borrow the constructor (unable to implement the function reuse), okay, then fix it, jsers Chi Chi also made a combination of inheritance

1. Concrete implementation
function Super () {    //only the basic and reference properties are declared here    this.val = 1;    This.arr = [1];}  The function is declared here SUPER.PROTOTYPE.FUN1 = function () {}; Super.prototype.fun2 = function () {};//super.prototype.fun3...function Sub () {    super.call (this);   Core    //...} Sub.prototype = new Super ();    Core var sub1 = new Sub (1), var sub2 = new Sub (2), alert (sub1.fun = = = Sub2.fun);   True
2. Core

The instance functions are placed on the prototype object to implement the function reuse. It also preserves the advantages of borrowing constructors by Super.call (this), inheriting the basic and reference properties of the parent class, and preserving the advantages of the ability to pass arguments, by Sub.prototype = new Super (), inheriting the parent function, and implementing the function reuse

3. Pros and cons

Advantages:

    1. There is no reference attribute sharing issue
    2. Can be passed the parameter
    3. Functions can be reused

Disadvantages:

    1. (Little flaw) there is a redundant parent instance attribute on the subclass prototype because the parent class constructor is called two times, generating two copies, and the child class instance has a mask on the subclass prototype. It's a waste of memory, better than the situation, but it's a flaw.

P.S. If you do not understand this "superfluous", you can view the breeze: JS Learning Note 2_ Object-oriented, the end of the article has more detailed explanation

Four. Parasitic combination inheritance (best way)

From the name can be seen is the optimization of the combination of inheritance, not to say that the combination of inheritance has flaws, it's okay, we went on to pursue perfection

1. Concrete implementation
function beget (obj) {   //child beget: Dragon Beget Dragon, Phoenix beget chicken.    var F = function () {};    F.prototype = obj;    return new F (); function Super () {    //only the basic and reference properties are declared here    this.val = 1;    This.arr = [1];}  The function is declared here SUPER.PROTOTYPE.FUN1 = function () {}; Super.prototype.fun2 = function () {};//super.prototype.fun3...function Sub () {    super.call (this);   Core    //...} var proto = Beget (Super.prototype); Core Proto.constructor = Sub;            Core Sub.prototype = Proto;              Core var sub = new sub (); Alert (sub.val); alert (Sub.arr);

p.s. Wait, baby. What is the function of a child? There are 3 words marked the core, why did not see it? Don't worry, let's have a cup of tea and watch.

2. Core

With beget (Super.prototype); cut off the extra copy of the parent instance property on the prototype object

P.s. What? You don't see it? Oh Oh ~, forget to say prototype and parasitic inheritance, say how always feel forget to lock the door. This memory

P.S. Parasitic combined inheritance, the name is not very appropriate, and the parasitic inheritance relationship is not particularly large

3. Pros and cons

Pros: Perfect.

Cons: Theoretically no (if the trouble with it is not a disadvantage.) )

P.S. Use up the trouble is on the one hand, on the other hand because the parasitic combined inheritance appears late, is the beginning of 21st century things, we can't wait so long, so the combination of inheritance is the most commonly used, and this theoretical perfect solution is only the best way to the textbook

Five. Prototype type

In fact, the completion of the above perfect plan can be finished, but from the combination of inheritance to the perfect plan seems to have a small leap of thought, it is necessary to tell the story clearly

1. Concrete implementation
function beget (obj) {   //child beget: Dragon Beget Dragon, Phoenix beget chicken.    var F = function () {};    F.prototype = obj;    return new F (); function Super () {    this.val = 1;    This.arr = [1];} Get the parent class object var sup = new Super ();//Birth child var sub = beget (SUP);   Core//Enhanced SUB.ATTR1 = 1;SUB.ATTR2 = 2;//sub.attr3...alert (sub.val);     1alert (Sub.arr);     1alert (SUB.ATTR1);   1

P.S. Yes, see, baby. Function Beget appeared.

2. Core

Use the child function to get a new "pure" object ("pure" because there is no instance attribute), and then gradually enhance it (populate instance properties)

P.S.ES5 provides the object.create () function, which internally is a prototype inheritance, ie9+ support

3. Pros and cons

Advantages:

    1. Deriving a new object from an existing object does not require creating a custom type (more like object replication than inheritance). )

Disadvantages:

    1. The prototype reference property is shared by all instances, because the entire parent class object acts as a subclass prototype object, so this flaw is unavoidable

    2. Code reuse is not possible (the new object is now available, the attribute is now added, all of the functions are not encapsulated, how to reuse)

P.S. Does this matter have much to do with inheritance? Why does Nicholas also list it as a way to achieve inheritance? Not a big relationship, but a relationship.

Six. Parasitic type

The name is too much, and the parasite is a pattern (routines), not only to implement inheritance

1. Concrete implementation
function beget (obj) {   //child beget: Dragon Beget Dragon, Phoenix beget chicken.    var F = function () {};    F.prototype = obj;    return new F (); function Super () {    this.val = 1;    This.arr = [1];} function Getsubobject (obj) {    //Create new object    var clone = beget (obj);//core//    enhanced    clone.attr1 = 1;    CLONE.ATTR2 = 2;    CLONE.ATTR3 ... return clone;} var sub = Getsubobject (New Super ()); alert (sub.val);     1alert (Sub.arr);     1alert (SUB.ATTR1);   1
2. Core

to prototype inheritance wearing a vest , it looks more like inheritance (the above-described prototype inheritance is more like object replication)

Note : The beget function is not required, in other words, to create a new object--enhanced--Returns the object, which is called parasitic inheritance, and how the new object is created is not important (with beget, new, the literal is now done. All can)

3. Pros and cons

Advantages:

    1. You still don't need to create a custom type

Disadvantages:

    1. Unable to implement function reuse (no use of prototypes, of course not)

P.S. Plot analysis: Defective parasitic inheritance + imperfect combination inheritance = perfect parasitic combined inheritance, you might as well go back to find out where to use the parasitic

Seven. Links to 6 ways of inheriting

P.s. Dashed lines indicate auxiliary action, solid lines indicate decisive effect

Resources
    • JavaScript Advanced Programming

    • The essence of JavaScript language

6 ways to re-understand JS's 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.