Basic explanation of JavaScript inheritance (prototype chain, borrow constructor, mixed mode, original type inheritance, parasitic inheritance, and parasitic combined inheritance) _ javascript skills

Source: Internet
Author: User
This article mainly introduces the basic explanation of JavaScript inheritance, prototype chain, borrow constructor, hybrid mode, original type inheritance, parasitic inheritance, and parasitic combined inheritance, for more information about JavaScript inheritance, see 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. For more information, see basic introduction to object-oriented JS, factory mode, constructor mode, prototype mode, hybrid mode, and dynamic prototype mode. Next we will talk about the methods used 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 the constructor function SuperType () {this. name = ['wuyuchang', 'jack', 'Tim']; this. property = true;} // Add method SuperType for parent type. prototype. getSuerperValue = function () {return this. property;} // create the constructor SubType () {this. test = ['h1 ', 'h2', 'h3 ', 'h4']; this. subproperty = false;} // The key step to implement inheritance. The prototype of the Child type points to the SubType of the parent type instance. 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. prototype. getSubValue = function () {return this. subproperty;}/* example of the test code */var instance1 = new SubType (); instance1.name. push ('wyc'); instance1.test. push ('h5'); alert (instance1.getSuerperValue (); // truealert (instance1.getSubValue (); // falsealert (instance1.name); // wuyuchang, Jack, Tim, wycalert (instance1.test); // h1, h2, h3, h4, h5var instance2 = new SubType (); alert (instance2.name); // wuyuchang, Jack, Tim, wycalert (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 after reading my blog post "basic introduction to object oriented JS, factory mode, constructor mode, prototype mode, hybrid mode, and dynamic prototype mode", my shoes will surely understand the existence of the prototype chain code.The first problem is that the prototype of the Child type is the parent type instance, that is, the attributes of the parent type contained in the child Type prototype, as a result, the prototype property of the reference type value will be shared by all instances.. The above code instance1.name. push ('wyc'); can prove the existence of this problem. The second problem of prototype chain is:When creating a child-type instance, parameters cannot be passed to a 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. Don't forget, a function is just an object that executes code in a specific environment, so you canUse the apply () or call () method to execute the constructor.. The Code is as follows:

// Create the constructor function SuperType (name) {this. name = name; this. color = ['pink ', 'yellow']; this. property = true; this. testFun = function () {alert (' http://tools.jb51.net/ ');} // Add method SuperType for parent type. prototype. getSuerperValue = function () {return this. property;} // create the constructor 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. prototype. getSubValue = function () {return this. subproperty;}/* 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://tools.jb51.net/ 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, bluevar instance2 = new SubType ('wyc'); instance2.testFun (); // http://tools.jb51.net/ Alert (instance2.name); // wyc // alert (instance2.getSuerperValue (); // error alert (instance2.test); // h1, h2, h3, h4alert (instance2.getSubValue (); // falsealert (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 for the child type, but 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. HoweverAfter the child type is instantiated, the method defined in the parent type cannot be called.GetSuperValue, which can only call the constructor method of the parent type: 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, of course it combines the advantages of both parties, that isThe prototype chain inherits attributes from the constructor.. The Code is as follows:

// Create the constructor function SuperType (name) {this. name = name; this. color = ['pink ', 'yellow']; this. property = true; this. testFun = function () {alert (' http://tools.jb51.net/ ');} // Add method SuperType for parent type. prototype. getSuerperValue = function () {return this. property;} // create the constructor 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. prototype. getSubValue = function () {return this. subproperty;}/* 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://tools.jb51.net/ Alert (instance1.name); // wuyuchang, Jack, Nick, helloalert (instance1.getSuerperValue (); // truealert (instance1.test); // h1, h2, h3, h4, h5 alert (instance1.getSubValue (); // false alert (instance1.color); // pink, yellow, bluevar instance2 = new SubType ('wyc'); instance2.testFun ();// http://tools.jb51.net/ Alert (instance2.name); // wyc alert (instance2.getSuerperValue (); // truealert (instance2.test); // h1, h2, h3, h4alert (instance2.getSubValue ()); // falsealert (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 annotations 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.