Basic explanation of JavaScript object-oriented inheritance

Source: Internet
Author: User
Tags constructor inheritance

It's a long time to explain JavaScript inheritance. If you don't talk nonsense, go to the topic.
 
Now that you want to learn about inheritance, it proves that you have a certain understanding of JavaScript object-oriented. If you have any questions, refer to the basic knowledge of object-oriented in JavaScript, next, we will generally use these methods to inherit JavaScript.
 
Prototype chain
 
The simplest way to implement inheritance in JavaScript is to use the prototype chain to direct the prototype of the child type to the parent type instance, that is, "Child type. prototype = new parent type (); ", the implementation method is as follows:
// Create a constructor for the parent type
Function SuperType (){
This. name = ['uyuchang', 'Jack', 'Tim'];
This. property = true;
}

// Add a method for the parent type
SuperType. prototype. getSuerperValue = function (){
Return this. property;
}

// Create a constructor for the child type
Function SubType (){
This. test = ['h1 ', 'h2', 'h3 ', 'h4'];
This. subproperty = false;
}

// Key steps to implement inheritance. The prototype of the child type points to the parent type instance.
SubType. prototype = new SuperType ();

// Add a method to the child type here. It must be inherited after implementation. Otherwise, the method is null when the pointer is directed to the parent type instance.
SubType. prototype. getSubValue = function (){
Return this. subproperty;
}

/* The following is an example of the test code */
Var instance1 = new SubType ();
Instance1.name. push ('wyc ');
Instance1.test. push ('h5 ');
Alert (instance1.getSuerperValue (); // true
Alert (instance1.getSubValue (); // false
Alert (instance1.name); // wuyuchang, Jack, Tim, wyc
Alert (instance1.test); // h1, h2, h3, h4, h5

Var instance2 = new SubType ();
Alert (instance2.name); // wuyuchang, Jack, Tim, wyc
Alert (instance2.test); // h1, h2, h3, h4
We can see that the above code is a simple inheritance implemented through the prototype chain, but there are still some problems in the test code example. I believe that my blog post explains how to understand the basic object-oriented knowledge in JavaScript. The first problem is that the prototype is a parent type instance, that is, the parent type attribute contained in the child type prototype, so that the prototype attribute of the reference type value is shared by all instances. The above code instance1.name. push ('wyc'); can prove the existence of this problem. The second problem of the prototype chain is that when creating a child-type instance, parameters cannot be passed to the super-type constructor. Therefore, in actual development, prototype chains are rarely used independently.
 
Borrow constructor
 
To solve the two problems in the prototype chain, developers began to use a technology called borrow constructor to solve the problems in the prototype chain. The implementation of this technology is quite simple. You only need to call the parent type constructor within the child type constructor. Do not forget that a function is only an object that executes code in a specific environment. Therefore, you can use the apply () or call () method to execute the constructor. The code is as follows:
// Create a constructor for the parent type
Function SuperType (name ){
This. name = name;
This. color = ['Pink ', 'yellow'];
This. property = true;

This. testFun = function (){
Alert ('http: // www.cnblogs.com/wuyuchang /');
    }
}

// Add a method for the parent type
SuperType. prototype. getSuerperValue = function (){
Return this. property;
}

// Create a constructor for the child type
Function SubType (name ){
SuperType. call (this, name );
This. test = ['h1 ', 'h2', 'h3 ', 'h4'];
This. subproperty = false;
}

// Add a method to the child type here. It must be inherited after implementation. Otherwise, the method is null when the pointer is directed to the parent type instance.
SubType. prototype. getSubValue = function (){
Return this. subproperty;
}


/* The following is an example of the test code */
Var instance1 = new SubType (['wuyuchang', 'Jack', 'Nick ']);
Instance1.name. push ('Hello ');
Instance1.test. push ('h5 ');
Instance1.color. push ('Blue ');
Instance1.testFun (); // http://www.cnblogs.com/wuyuchang/
Alert (instance1.name); // wuyuchang, Jack, Nick, hello
// Alert (instance1.getSuerperValue (); // error
Alert (instance1.test); // h1, h2, h3, h4, h5
Alert (instance1.getSubValue (); // false
Alert (instance1.color); // pink, yellow, blue

Var instance2 = new SubType ('wyc ');
Instance2.testFun (); // http://www.cnblogs.com/wuyuchang/
Alert (instance2.name); // wyc
// Alert (instance2.getSuerperValue (); // error
Alert (instance2.test); // h1, h2, h3, h4
Alert (instance2.getSubValue (); // false
Alert (instance2.color); // pink, yellow
We can see that the constructor of SubType in the code above calls the parent type "SuperType. call (this, name); "to realize the inheritance of attributes. You can also pass parameters for the parent type when creating an instance of the child type. However, a new problem arises. As you can see, I defined a method in the parent constructor: testFun, and defined a method in the parent type prototype: getSuperValue. However, after the child type is instantiated, the getSuperValue method defined in the parent type's prototype cannot be called, and the method of the constructor in the parent type can only be called: testFun. This is the same as using only the constructor mode in the creation object, so that the function is not reusable. Considering these issues, the techniques for borrowing constructors are rarely used independently.
 
Combination inheritance (prototype chain + borrow constructor)
 
As the name implies, combined inheritance is a mode that combines the advantages of prototype chain and borrow constructor. The implementation is also very simple. Since it is a combination, it certainly combines the advantages of both parties, that is, the prototype chain inheritance method, while the constructor inherits attributes. The code is as follows:
// Create a constructor for the parent type
Function SuperType (name ){
This. name = name;
This. color = ['Pink ', 'yellow'];
This. property = true;

This. testFun = function (){
Alert ('http: // www.cnblogs.com/wuyuchang /');
    }
}

// Add a method for the parent type
SuperType. prototype. getSuerperValue = function (){
Return this. property;
}

// Create a constructor for the child type
Function SubType (name ){
SuperType. call (this, name );
This. test = ['h1 ', 'h2', 'h3 ', 'h4'];
This. subproperty = false;
}

SubType. prototype = new SuperType ();

// Add a method to the child type here. It must be inherited after implementation. Otherwise, the method is null when the pointer is directed to the parent type instance.
SubType. prototype. getSubValue = function (){
Return this. subproperty;
}

/* The following is an example of the test code */
Var instance1 = new SubType (['wuyuchang', 'Jack', 'Nick ']);
Instance1.name. push ('Hello ');
Instance1.test. push ('h5 ');
Instance1.color. push ('Blue ');
Instance1.testFun (); // http://www.cnblogs.com/wuyuchang/
Alert (instance1.name); // wuyuchang, Jack, Nick, hello
Alert (instance1.getSuerperValue (); // true
Alert (instance1.test); // h1, h2, h3, h4, h5
Alert (instance1.getSubValue (); // false
Alert (instance1.color); // pink, yellow, blue

Var instance2 = new SubType ('wyc ');
Instance2.testFun (); // http://www.cnblogs.com/wuyuchang/
Alert (instance2.name); // wyc
Alert (instance2.getSuerperValue (); // true
Alert (instance2.test); // h1, h2, h3, h4
Alert (instance2.getSubValue (); // false
Alert (instance2.color); // pink, yellow
The above code uses SuperType. call (this, name); to inherit the attributes of the parent type, and uses SubType. prototype = new SuperType (); to inherit the methods of the parent type. The above code easily solves the problems encountered by the prototype chain and borrow constructor, and becomes the most common method for inheriting instances in JavaScript. However, the hybrid mode does not have any disadvantages. We can see that the property of the parent type is actually inherited when the method is inherited in the above code, but the reference type is shared at this time, therefore, the sub-type constructor calls the parent constructor to inherit the attributes of the parent type and overwrite the attributes inherited in the prototype, it is obviously unnecessary to call the constructor twice in this way, but what can be done? To solve this problem, first look at the following two modes.
 
Original type inheritance
 
The implementation method of the original type inheritance is different from that of the ordinary inheritance. The original type inheritance does not use constructors in a strict sense. Instead, the prototype can be used to create new objects based on existing objects, you do not need to create a custom type. The code is as follows:
Function object (o ){
Function F (){}
F. prototype = o;
Return new F ();
}
Sample code:
/* Original type inheritance */
Function object (o ){
Function F (){}
F. prototype = o;
Return new F ();
}

Var person = {
Name: 'wuyuchang ',
Friends: ['wyc', 'Nicholas ', 'Tim']
}

Var anotherPerson = object (person );
AnotherPerson. name = 'Greg ';
AnotherPerson. friends. push ('Bob ');

Var anotherPerson2 = object (person );
AnotherPerson2.name = 'Jack ';
AnotherPerson2.friends. push ('Rose ');

Alert (person. friends); // wyc, Nicolas, Tim, Bob, Rose
Parasitic inheritance
/* Parasitic inheritance */
Function createAnother (original ){
Var clone = object (original );
Clone. sayHi = function (){
Alert ('hi ');
    }
Return clone;
}
Example:
/* Original type inheritance */
Function object (o ){
Function F (){}
F. prototype = o;
Return new F ();
}
    
/* Parasitic inheritance */
Function createAnother (original ){
Var clone = object (original );
Clone. sayHi = function (){
Alert ('hi ');
    }
Return clone;
}

Var person = {
Name: 'wuyuchang ',
Friends: ['wyc', 'Nicholas ', 'rose']
}
Var anotherPerson = createAnother (person );
AnotherPerson. sayHi ();
Parasitic combined inheritance
 
We have mentioned the disadvantages of implementing inheritance in the combined Crip mode. Now we can solve the disadvantages. The implementation idea is that for the constructor to inherit attributes, and the prototype chain to inherit in the mixed form, that is, you do not need to instantiate the parent type constructor when inheriting the method. The code is as follows:
Function object (o ){
Function F (){}
F. prototype = o;
Return new F ();
}

/* Parasitic combined inheritance */
Function inheritPrototype (subType, superType ){
Var prototype = object (superType. prototype );
Prototype. constructor = subType;
SubType. prototype = prototype;
}
During use, you only need to replace "SubType. prototype = new SuperType ();" in the combination mode with inheritPrototype (subType, superType. The high efficiency of parasitic combined inheritance is that it only calls the parent type constructor once, avoiding unnecessary or unnecessary attributes. At the same time, the prototype chain can remain unchanged, so instanceof and isPrototypeof () can be used normally (). This is also the most ideal inheritance method currently, and is also transforming to this mode. (YUI also uses this mode .)
 
This blog reference JavaScript advanced programming version 3rd, the code is rewritten, more specific and added notes to make everyone easier to understand. For example, if you have unique insights on JS inheritance, please feel free to reply to your comments for your reference!

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.