JSPro-in-depth explanation of inheritance of object-oriented programming _ javascript skills

Source: Internet
Author: User
The general object-oriented programming language has two inheritance Methods: interfaceinheritance and implementationinheritance ). Interface inheritance only inherits the method signature, while implementation inheritance inherits the actual method. In JavaScript, functions do not have signatures. Therefore, JavaScript only supports implementation inheritance and relies mainly on prototypechaining. Prototype chaining ):

Use prototype to inherit attributes and methods. Review the relationships between constructor, prototype, and instance. Each constructor has a prototype attribute pointing to a prototype object. prototype objects also have the constructor attribute pointing to this function; the instance also has an internal pointer (_ proto _) pointing to this prototype object. What if this prototype object is an instance of another object? In this way, the prototype object contains a pointer to another type. Correspondingly, another prototype also contains a pointer to another constructor.

JS inheritance is very simple. It is to set prototype of the subclass as a (instantiated) object of the parent class.

The Code is as follows:


Function SuperType (){
This. property = true;
}

SuperType. prototype. getSuperValue = function (){
Return this. property;
};

Function SubType (){
This. subproperty = false;
}

// Inherit from SuperType
SubType. prototype = new SuperType ();

SubType. prototype. getSubValue = function (){
Return this. subproperty;
};

Var instance = new SubType ();
Alert (instance. getSuperValue (); // true


Final result: the _ proto _ of the instance points to the SubType. prototype object, while the _ proto _ attribute of the SubType. prototype object points to the SuperType. prototype object. GetSuperValue () is a method, so it still exists in the prototype, and property is an instance property, so it is now in the SubType. prototype instance. Instance. constructor now points to SuperType, because SubType. prototype points to SuperType. prototype, while the constructor attribute of SuperType. prototype points to SuperType function, so instance. constructor points to SuperType.

By default, all reference types inherit objects. This is because the prototype Object of all functions is an instance of the Object by default, so the internal Prototype (_ proto _) points to Object. prototype.

Relationship between prototype and instance:You can use two methods to determine the relationship between the prototype and the instance.
-Instancef OPERATOR: This operator is used to test constructors that have occurred in the instance and prototype chain. true is returned.

The Code is as follows:


Alert (instance instanceof Object); // true
Alert (instance instanceof SuperType); // true
Alert (instance instanceof SubType); // true


-IsPrototypeOf () method: any prototype that has appeared in the prototype chain can be said to be the prototype of the Instance derived from the prototype chain.

The Code is as follows:


Alert (Object. prototype. isPrototypeOf (instance); // true
Alert (SuperType. prototype. isPrototypeOf (instance); // true
Alert (SubType. prototype. isPrototypeOf (instance); // true


Note: We sometimes add methods to the subclass or override some methods of the parent class. Note that these methods must be defined after inheritance. In the following example, after SubType inherits SuperType, we add a new method getSubValue () to it and overwrite the getSuperValue () method. For the latter, only the SubType instance will use the override method, and the SuperType instance will still use the original getSuperValue () method.

The Code is as follows:


Function SuperType (){
This. property = true;
}
SuperType. prototype. getSuperValue = function (){
Return this. property;
};
Function SubType (){
T his. subproperty = false;
}
// Inherit from SuperType
SubType. prototype = new SuperType ();
// New method
SubType. prototype. getSubValue = function (){
Return this. subproperty;
};
// Override existing method
SubType. prototype. getSuperValue = function (){
Return false;
};
Var instance = new SubType ();
Alert (instance. getSuperValue (); // false


Another thing to note is that when the prototype chain is used for inheritance, you cannot use the object literal to create the prototype method, because this will overwrite the prototype chain. The following code uses the object literal to add a method to the prototype after the SubType inherits the SuperType. However, in this way, the SubType prototype is overwritten and the SubType is overwritten. prototype contains an Object instance, which also disconnects the SuperType.

The Code is as follows:


Function SuperType (){
This. property = true;
}
SuperType. prototype. getSuperValue = function (){
Return this. property;
};
Function SubType (){
This. subproperty = false;
}
// Inherit from SuperType
SubType. prototype = new SuperType ();
// Try to add new methods-this nullifies the previous line
SubType. prototype = {
GetSubValue: function (){
Return this. subproperty;
},
SomeOtherMethod: function (){
Return false;
}
};
Var instance = new SubType ();
Alert (instance. getSuperValue (); // error!


Prototype chain problems:Like a prototype, a prototype chain may fail when a reference type value is used. Review the previous content. The prototype attribute containing a reference type value will be shared by all instances. This is why we need to define the reference type value in the constructor, rather than in the prototype. When the prototype chain is used to implement the inheritance, the prototype will actually become another type of instance, so the original Instance attributes will also become the current prototype attributes.

The Code is as follows:


Function SuperType (){
This. colors = ["red", "blue", "green"];
}
Function SubType (){
}
// Inherit from SuperType
SubType. prototype = new SuperType ();
Var instance1 = new SubType ();
Instance1.colors. push ("black ");
Alert (instance1.colors); // "red, blue, green, black"
Var instance2 = new SubType ();
Alert (instance2.colors); // "red, blue, green, black"


In the SuperType constructor, we define a colors array. Each SuperType instance has its own colors array. However, after the SubType inherits the SuperType using the prototype chain, the SubType. prototype becomes an instance of the SuperType, so it has its own colors attribute, that is, the SubType. prototype. colors attribute. Therefore, when a SubType instance is created, all instances share this attribute. As shown in the code above.

The second problem is: when creating a subclass instance, you cannot pass parameters to the super class constructor. In fact, it should be said that there is no way to pass parameters to the super class constructor without affecting all object instances. Due to these problems, we will not use the prototype chain independently.

--------------------------------------------------------------------------------

Contructor stealing ):
To solve these problems, developers have invented a technology called borrow constructor. The idea of this technology is to call a super-Type constructor within the sub-Type constructor. (A function is just an object that executes code in a specific environment ?) We can use the apply () or call () method to execute the constructor on the newly created object.

The Code is as follows:


Function SuperType (){
This. colors = ["red", "blue", "green"];
}
Function SubType (){
// Inherit from SuperType
SuperType. call (this );
}
Var instance1 = new SubType ();
Instance1.colors. push ("black ");
Alert (instance1.colors); // "red, blue, green, black"
Var instance2 = new SubType ();
Alert (instance2.colors); // "red, blue, green"


We use the call () method in SubType to call the SuperType constructor. In fact, we execute all the object initialization code defined in the SuperType () function on the new SubType object. The result is that each SubType instance has its own copy of the colors attribute.

Passing parameters: a major benefit of using the borrow constructor method is that we can pass parameters from the constructor of the subclass to the constructor of the parent class.

The Code is as follows:


Function SuperType (name ){
This. name = name;
}
Function SubType (){
// Inherit from SuperType passing in an argument
SuperType. call (this, "Nicholas ");
// Instance property
This. age = 29;
}
Var instance = new SubType ();
Alert (instance. name); // "Nicolas ";
Alert (instance. age); // 29


The new SuperType constructor adds a parameter name. When calling SuperType, we pass the parameter "Nicolas" to SuperType ". To prevent a super-Type constructor from overwriting sub-type attributes, you can define the attributes of sub-classes after calling the super-Type constructor.

Questions about borrow constructors:Methods are defined in constructors and cannot be reused. In addition, the methods defined in the super-type prototype are invisible to sub-types. Only the constructor mode can be used for all types of results.

--------------------------------------------------------------------------------

Combination inheritance:
An inheritance mode that combines the advantages of the prototype chain and borrow constructor. Use the prototype chain to inherit the prototype attributes and methods, and use the borrow constructor to inherit the instance attributes. In the following example, we use the call () method to call the SuperType Constructor (each SubType instance has its own name and colors attributes, and the age attribute of SubType ); then assign the SuperType instance to the SubType prototype so that it inherits the SuperType sayName () method (this method is shared by each instance ).

The Code is as follows:


Function SuperType (name ){
This. name = name;
This. colors = ["red", "blue", "green"];
}

SuperType. prototype. sayName = function (){
Alert (this. name );
};

Function SubType (name, age ){
// Inherit properties
SuperType. call (this, name );
This. age = age;
}
// Inherit methods
SubType. prototype = new SuperType ();
SubType. prototype. sayAge = function (){
Alert (this. age );
};

Var instance1 = new SubType ("Nicolas", 29 );
Instance1.colors. push ("black ");
Alert (instance1.colors); // "red, blue, green, black"
Instance1.sayName (); // "Nicolas ";
Instance1.sayAge (); // 29
Var instance2 = new SubType ("Greg", 27 );
Alert (instance2.colors); // "red, blue, green"
Instance2.sayName (); // "Greg ";
Instance2.sayAge (); // 27


Original Type Inheritance (Prototypal Inheritance ):

The Code is as follows:


Function object (o ){
Function F (){}
F. prototype = o;
Return new F ();
}
--------------------------------------------------------------------------------


Parasitic Inheritance ):

Constructor

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.