Inheritance of JavaScript classes

Source: Internet
Author: User
Use the shared prototype to implement inheritance
Inheritance is another important concept of object-oriented development. It can correspond the concepts of real life Program Logical. For example, fruit is a class with some public properties, while Apple is also a class, but they belong to fruit, so Apple should inherit from fruit.
There is no special mechanism in JavaScript to implement class inheritance, but it can be inherited by copying the prototype of a class to another class. A simple implementation is as follows:
Fucntion class1 (){
// Constructor
}

Function class2 (){
// Constructor
}
Class2.prototype = class1.prototype;
Class2.prototype. moreproperty1 = "XXX ";
Class2.prototype. moremethod1 = function (){
// Method implementation Code
}
VaR OBJ = new class2 ();
In this way, class2 has the same prototype as class1. without considering constructors, the two classes are equivalent. Then, two additional methods were assigned to class2 through prototype. Therefore, class2 adds attributes and methods on the basis of class1. this achieves class inheritance.
Javascript provides the instanceof operator to determine whether an object is an instance of a certain class. For the OBJ object created above, the following two statements are true:
OBJ instanceof class1
OBJ instanceof class2
On the surface, the above implementation is completely feasible, and javascript can correctly understand this inheritance relationship. obj is an instance of both class1 and class2. This is not correct. This understanding of JavaScript is actually based on a very simple strategy. Take a look at the following code. First Use prototype to make class2 inherit from class1, and then repeatedly define the method in class2:
<Script language = "JavaScript" type = "text/JavaScript">
<! --
// Define class1
Function class1 (){
// Constructor
}
// Define the class1 Member
Class1.prototype = {
M1: function (){
Alert (1 );
}
}
// Define class2
Function class2 (){
// Constructor
}
// Let class2 inherit from class1
Class2.prototype = class1.prototype;
// Repeat the method defined for class2
Class2.prototype. method = function (){
Alert (2 );
}
// Create two class instances
VaR obj1 = new class1 ();
VaR obj2 = new class2 ();
// Call the method methods of the two objects respectively
Obj1.method ();
Obj2.method ();
// -->
</SCRIPT>
The code execution result shows that the dialog box "2" is displayed ". It can be seen that when the prototype of class2 is changed, the prototype of class1 also changes. Even if the prototype of class2. Therefore, class1 and class2 are only two classes with different constructors. They maintain the same member definition. From this point, I believe that the readers have discovered the secret: the prototype of class1 and class2 are identical and are referenced by the same object. It can be seen from this value assignment statement:
// Let class2 inherit from class1
Class2.prototype = class1.prototype;
In JavaScript, except for basic data types (numbers, strings, Boolean, etc.), all values and function parameters are passed by reference instead of by value. Therefore, the preceding statement only allows the prototype object of class2 to reference the prototype of class1, resulting in consistent class member definitions. We can also see the execution mechanism of the instanceof operator, which is to judge whether an object is a prototype instance, because the obj1 and obj2 correspond to the same prototype, therefore, the instanceof results are the same.
Therefore, using prototype to reference copying to implement inheritance is not a correct method. However, when the requirements are not strict, it is also a reasonable method. The only constraint is that the overwrite definition of Class Members is not allowed. The following section uses the reflection mechanism and prototype to implement correct class inheritance.
Use reflection mechanism and prototype to implement inheritance
The sharing prototype introduced in the previous section to implement class inheritance is not a good method. After all, two classes are shared prototypes, and any redefinition of Members will affect each other, it is not an inheritance of strict meaning. However, on the basis of this idea, we can use the reflection mechanism to implement class inheritance. The idea is as follows: Use (... In ...) The statement lists all the members of the base class prototype and assigns them to the prototype object of the subclass. For example:
<Script language = "JavaScript" type = "text/JavaScript">
<! --
Function class1 (){
// Constructor
}
Class1.prototype = {
Method: function (){
Alert (1 );
},
Method2: function (){
Alert ("method2 ");
}
}
Function class2 (){
// Constructor
}
// Let class2 inherit from class1
For (var p in class1.prototype ){
Class2.prototype [p] = class1.prototype [p];
}

// Override the method defined in class1
Class2.prototype. method = function (){
Alert (2 );
}
// Create two class instances
VaR obj1 = new class1 ();
VaR obj2 = new class2 ();
// Call the methods of obj1 and obj2 respectively.
Obj1.method ();
Obj2.method ();
// Call the method2 methods of obj1 and obj2 respectively.
Obj1.method2 ();
Obj2.method2 ();
// -->
</SCRIPT>
From the running results, we can see that the repeated methods defined in obj2 already overwrite the inherited method, and the method2 method is not affected. In addition, the method in obj1 still maintains the original definition. In this way, the inheritance of classes with the correct meaning is realized. To facilitate development, you can add a common method for each class to implement class inheritance:
// Add a static method for the class. inherit indicates that the method inherits from a class.
Function. Prototype. inherit = function (baseclass ){
For (var p in baseclass. Prototype ){
This. Prototype [p] = baseclass. Prototype [p];
}
}
Here we use the common class functions of all function objects (classes) to add inheritance methods, so that all classes will have an inherit method to implement inheritance. Readers can understand this usage carefully. Therefore, in the code above:
// Let class2 inherit from class1
For (var p in class1.prototype ){
Class2.prototype [p] = class1.prototype [p];
}
It can be rewritten:
// Let class2 inherit from class1
Class2.inherit (class1)
This makes the code logic clearer and easier to understand. One disadvantage of inheritance implemented through this method is that when adding class member definitions in class2, prototype cannot be directly assigned, but its attributes can only be assigned. For example, it cannot be written:
Class2.prototype = {
// Member Definition
}
However, it can only be written as follows:
Class2.prototype. propertyname = somevalue;
Class2.prototype. methodname = function (){
// Statement
}
It can be seen that the implementation of inheritance is still at the cost of code readability. In the next section, we will introduce the prototype-1.3.1 framework (Note: The prototype-1.3.1 frame is a javascript class library, extends the basic object functions and provides utilities. For more information, see the appendix .) Not only can the base class be directly assigned to the property with an object, but can also be implemented in the derived class to make the code logic clearer, it can also better reflect the characteristics of object-oriented languages.

Implementation Mechanism of class inheritance in prototype-1.3.1 framework
In the prototype-1.3.1 framework, an extend method is first defined for each object:
// Add a static method for the object class: Extend
Object. Extend = function (destination, source ){
For (property in source ){
Destination [property] = source [property];
}
Return destination;
}
// Use the object class to add the extend method for each object
Object. Prototype. Extend = function (object ){
Return object. Extend. Apply (this, [This, object]);
}
The object. Extend method is easy to understand. It is a static method of the object class. It is used to assign all the properties of source in the parameter to the destination object and return the reference of destination. The following describes the implementation of object. Prototype. Extend. Because object is the base class of all objects, an extend method is added for all objects. The statement in the function body is as follows:
Object. Extend. Apply (this, [This, object]);
This statement runs the static method of the object class as the method of the object. The first parameter This is pointing to the object instance itself, and the second parameter is an array containing two elements: object itself and the passed object parameter object. The function assigns all attributes and methods of the parameter object to the object that calls the method and returns its reference. With this method, we can see the implementation of class inheritance below:
<Script language = "JavaScript" type = "text/JavaScript">
<! --
// Define the extend Method
Object. Extend = function (destination, source ){
For (property in source ){
Destination [property] = source [property];
}
Return destination;
}
Object. Prototype. Extend = function (object ){
Return object. Extend. Apply (this, [This, object]);
}
// Define class1
Function class1 (){
// Constructor
}
// Define the class class1 Member
Class1.prototype = {
Method: function (){
Alert ("class1 ");
},
Method2: function (){
Alert ("method2 ");
}

}
// Define class2
Function class2 (){
// Constructor
}
// Let class2 inherit from class1 and define new members
Class2.prototype = (New class1 (). Extend ({
Method: function (){
Alert ("class2 ");
}
});

// create two instances
var obj1 = new class1 ();
var obj2 = new class2 ();
// test the obj1 and obj2 methods
obj1.method ();
obj2.method ();
obj1.method2 ();
obj2.method2 ();
// -->

the running result shows that the inheritance is correctly implemented, in addition, the additional members of the derived class can also be defined in the form of a list, improving the readability of the Code. The inheritance implementation is explained below:
// Let class2 inherit from class1 and define new members
class2.prototype = (New class1 ()). extend ({
method: function () {
alert ("class2");
}< BR> });
the code above can also be written as follows:
// Let class2 inherit from class1 and define a new member
class2.prototype = class1.prototype. extend ({
method: function () {
alert ("class2");
}< BR> });
however, because the extend method changes the value of prototype of class1. In the prototype-1.3.1 framework, new class1 () is cleverly used to create an instance object and assign the members of the Instance Object to the prototype of class2. In essence, it is equivalent to creating a copy of the prototype of class1. Operations on this copy will naturally not affect the definition of prototype in the original class.

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.