DOM note (13): inheritance of JavaScript

Source: Internet
Author: User

DOM note (13): inheritance of JavaScript

Java, C ++, C #, and other OO languages support two inheritance Methods: interface inheritance and implementation inheritance. The interface inherits the method signature, while the inheritance inherits the actual methods and attributes. In SCMAScript, because the function does not have a signature, it cannot implement interface inheritance. It only supports implementation inheritance.

Implementation inheritance mainly relies on the prototype chain.

I. prototype chain

A prototype chain uses a prototype to let a reference type inherit another reference type. In DOM note (12): Let's talk about prototype objects, describes the relationships between constructors, instances, and prototypes:

 

Each constructor has a prototype object. The prototype object contains a pointer to the constructor, and each instance contains an internal pointer to the prototype object. What if the prototype object is used as an instance of another constructor?

Function SuperType () {this. property = true;} SuperType. prototype. getSuperValue = function () {return this. property ;}; function SubType () {this. subproperty = false;} // inherits the SuperTypeSubType. prototype = new SuperType (); SubType. prototype. getSubValue = function () {return this. subproperty;}; var instance = new SubType (); alert (instance. getSuperValue (); // true

 

DOM note (11): basic understanding of JavaScript objects and Object types are the root elements of all objects. Therefore, the SubType inherits the Object, and there is a prototype inside which the Pointer Points to the Object. Now their relationship is like this:

 

When the instance calls getSuperValue (), it will search: 1) Search in the instance; 2) if it cannot be found in the instance, it will be in the SubType. search in prototype; 3) search in SubType. prototype cannot be found, it is in SuperType. in prototype. Click it to stop searching and return the result value. However, when the instance calls toString (), it will always search for the end-Object. prototype of the prototype chain.

According to the prototype chain, it should be noted that instance. constructor no longer points to SubType, but to SuperType.

Ii. Summary of prototype inheritance

1. determine the relationship between the prototype and the instance

In DOM note (12): I also mentioned the isPrototypeOf () method in the prototype object. In addition, I can use instanceof to establish the existence of this relationship.

// Truealert (instance instanceof Object); alert (instance instanceof SuperType); alert (instance instanceof SubType); alert (Object. prototype. isPrototypeOf (instance); alert (SuperType. prototype. isPrototypeOf (instance); alert (SubType. prototype. isPrototypeOf (instance ));

 

2. When the subclass defines attributes and methods with the same name as the parent class, the corresponding attributes and methods of the parent class will be blocked.

Function SuperType () {this. property = true;} SuperType. prototype. getSuperValue = function () {return this. property ;}; function SubType () {this. property = false; // attributes with the same name} // inherits the SuperTypeSubType. prototype = new SuperType (); SubType. prototype. getSubValue = function () {return this. property ;}; var instance = new SubType (); alert (instance. getSuperValue (); // false
3. prototype chain implementation inheritance. You cannot use the object literal to create a prototype method to avoid rewriting the prototype chain.
Function SuperType () {this. property = true;} SuperType. prototype. getSuperValue = function () {return this. property ;}; function SubType () {this. subproperty = false;} // inherits the SuperTypeSubType. prototype = new SuperType (); // use the literal to add a new method, resulting in the previous row being invalid SubType. prototype = {getSubValue: function () {return this. subproperty ;}}; var instance = new SubType (); alert (instance. getSuperValue (); // error: undefined is not a function

 

4. There are two problems with prototype inheritance: 1) the prototype attributes of the reference type will be shared by all instances; 2) when the prototype is inherited, parameters cannot be passed to the constructor of the parent class through a subclass instance.

Function SuperType () {this. colors = [red, blue, white];} function SubType () {}// inherits SuperTypeSubType. prototype = new SuperType (); var instance1 = new SubType (); instance1.colors. push (black); alert (instance1.colors); // red, blue, white, blackvar instance2 = new SubType (); alert (instance2.colors); // red, blue, white, black

 

Instance1 and instance2 share the colors array attribute (reference type ).

Iii. Other inheritance Methods

1. Borrow Constructor

When prototype inheritance is used, the prototype attributes of the reference type are shared by all instances. However, the borrow constructor can avoid this problem, and can use apply () and call () to pass parameters to the constructor of the parent class:

Function SuperType () {this. colors = [red, blue, white];} function SubType () {// inherits SuperType. call (this);} var instance1 = new SubType (); instance1.colors. push (black); alert (instance1.colors); // red, blue, white, blackvar instance2 = new SubType (); alert (instance2.colors); // red, blue, white
2. Combination inheritance (recommended)Combination inheritance: Prototype inheritance + constructor inheritance: prototype chain inherits prototype attributes and methods, and constructor inherits instance attributes.
Function SuperType (name) {this. name = name; this. colors = [red, blue, white];} SuperType. prototype. sayName = function () {alert (this. name) ;}; function SubType (name, age) {// inherits the SuperType attribute and passes the parameter to the constructor SuperType of the parent class. call (this, name); // call SuperType () this for the first time. age = age;} // inherit the SubType of the SuperType method. prototype = new SuperType (); // The second call of SuperType () SubType. prototype. constructor = SubType; SubType. prototype. sayAge = function () {alert (this. age) ;}; var instance1 = new SubType (dwqs, 20); instance1.colors. push (black); alert (instance1.colors); // red, blue, white, blackinstance1.sayName (); // dwqsinstance1.sayAge (); // 20var instance2 = new SubType (i94web, 25); alert (instance2.colors); // red, blue, whiteinstance2.sayName (); // i94webinstance2. sayAge (); // 25

 

To ensure that the SuperType constructor does not override the prototype of the subclass, we recommend that you add the attributes of the subclass after calling the parent class constructor. The disadvantage of combination inheritance is: 1) in any situation, the parent class constructor will be called twice; 2) The subclass needs to override the attributes in the parent class, there are also two groups of name and colors attributes (parent class attributes): one group is on the instance and the other is on the prototype. 3. Original Type inheritanceThis method creates a new object based on an existing object without creating a custom type. However, the following function is required:
function object(o){    function F(){}    F.prototype=o;    return new F();}
O is an existing object. The returned object has the same attributes and methods as o.
Var person = {name: "dwqs", colors: [red, blue, white]}; var per1 = object (person); alert (per1.name ); // dwqs // overwrite the existing attribute per1.name = "i94web"; per1.age = 20; // Add the attribute alert (per1.age); // 20per1. colors. push ("black"); alert (per1.name); // i94webalert (per1.colors); // red, blue, white, blackvar per2 = object (person); alert (per2.name ); // dwqs // all instances share the reference type attributes alert (per2.colors); // red, blue, white, black

The chaotic relationship is as follows:

 

Per1 and per2 share the colors attribute (reference type ). In ECMAScript 5, Object. create (obj, [props]) Standardizes this method: obj is an existing Object, and props is optional. It is an Object that contains additional attributes, format and Object. the second parameter of defineProperties () is in the same format.

var person={    name:dwqs,    colors:[red,blue,white]};var per1 = Object.create(person,{    age:{        value:20    }});alert(per1.age);  //20

 

4. Parasitic inheritance

This method is similar to the original type inheritance. You also need to borrow the object function and then enhance the object in some internal way.

Function object (o) {function F () {} F. prototype = o; return new F ();} var person = {name: dwqs, colors: [red, blue, white]}; function createObj (obj) {var clone = object (obj); // enhances object clone. age = 20; clone. hello = function () {alert (Hello, my age is + this. age) ;}; return clone;} var per1 = createObj (person); per1.Hello (); // Hello, my age is 20

 

5. Parasitic combined inheritance

In method 2nd, although the most common method of JavaScript clock is combined inheritance, there are also deficiencies. As mentioned above, we will not repeat it here. The parasitic combined inheritance can solve these two problems. The basic mode is as follows:

Function object (o) {function F () {} F. prototype = o; return new F ();} function inheritPrototype (subType, superType) {var obj = object (superType. prototype); // create object obj. constructor = subType; // enhancement object subType. prototype = obj; // specified object}

 

Example of rewriting combination inheritance:

Function object (o) {function F () {} F. prototype = o; return new F ();} function inheritPrototype (subType, superType) {var obj = object (superType. prototype); // create object obj. constructor = subType; // enhancement object subType. prototype = obj; // specify the object} function SuperType (name) {this. name = name; this. colors = [red, blue, white];} SuperType. prototype. sayName = function () {alert (this. name) ;}; function SubType (name, age) {// inherits the SuperType attribute and passes the parameter to the constructor SuperType of the parent class. call (this, name); this. age = age;} inheritPrototype (SubType, SuperType); SubType. prototype. sayAge = function () {alert (this. age) ;}; var instance1 = new SubType (dwqs, 20); instance1.colors. push (black); alert (instance1.colors); // red, blue, white, blackinstance1.sayName (); // dwqsinstance1.sayAge (); // 20var instance2 = new SubType (i94web, 25); alert (instance2.colors); // red, blue, whiteinstance2.sayName (); // i94webinstance2. sayAge (); // 25

 

Only one SuperType () constructor is called, and unnecessary attributes are not created on SuperType. prototype. The prototype chain remains unchanged and the instanceof and isPrototypeOf () methods can be used.

 

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.