Home >Web Front-end >JS Tutorial >JavaScript object-oriented programming basics: inheritance_js object-oriented
We see how straightforward the concept of inheritance here is, "copy the prototype of one class to another class", okay, Code is cheap, look at the code:
function class1() { }
function class2() { }
class2.prototype = class1.prototype;
class2.moreProperty1 = " class 2 additional string " ;
class2.moreMethod1 = function () { alert( " class 2 additional method " ) ; }
/*
In this way, first of all, class2 has the same prototype as class1. Regardless of the constructor, the two classes are equivalent.
Subsequently, two additional methods were given to class2 through prototype. So class2 adds attributes and methods based on class1
, which realizes class inheritance.
*/
function test() {
var obj = new class2();
// JavaScript provides the instanceof operator to determine whether an object is an instance of a certain class
alert(obj instanceof class2); // true
alert(obj instanceof class1); // ?
}
Run the code, is the result what we expected? On the surface, the above implementation is completely feasible, and js can also correctly understand and implement this inheritance relationship. obj is an instance of both class1 and class2, but in fact it is not (the purpose of our study is to know more about it) The reason why). This understanding of js is actually based on a very simple strategy. Look at the code below. First use prototype to make class2 inherit from class1, and then repeatedly define the method method in class2:
// Define class1
function class1() {
//Constructor
}
// Define members of class1
class1.prototype = {
m1: function () { // Method 1
alert( " class1 method1 " );
}
}
// Define class2
function class2() {
// Constructor
}
// Let class2 Inherited from class1
class2.prototype = class1.prototype;
// Repeatedly define method method for class2
class2.prototype.method = function () {
alert( " whose method2? class1 or class2 " );
}
// Create instances of two classes
var obj1 = new class1();
var obj2 = new class2();
function test() {
// Call the method methods of the two objects respectively
obj1.method();
obj2.method();
}
Judging from the code execution results , the result of method running in class1 and class2 is the same.
It can be seen that when the prototype of class2 is changed, the prototype of class1 will also change accordingly. Even if some members are added or removed from the prototype of class2, the members of class1 will also change accordingly. So class1 and class2 are just two classes with different constructors, but they maintain the same member definitions. At this point, I believe readers have discovered the secret: the prototypes of class1 and class2 are exactly the same and refer to the same object. In fact, it can be seen from this assignment statement:
//Let class2 inherit from class1
class2.prototype=class1.prototype;
In js, in addition to basic data types (numbers, strings, Boolean type, etc.), all assignments and function parameters are passed by reference, not by value. Therefore, the above statement only allows the prototype object of class2 to refer to the prototype of class1, resulting in the effect that the class member definitions are always consistent. From here we also see the execution mechanism of the instanceof operator, which is to determine whether an object is an instance of prototype. Because obj1 and obj2 here correspond to the same prototype, the results of their instanceof are the same. It can be seen that using prototype reference copy to implement inheritance is not a correct method. But when the requirements are not strict, it is also a reasonable method. The only constraint is that overriding definitions of class members is not allowed (this is actually a reflection of the flexibility of js). In fact, we can completely use the reflection mechanism and prototype to achieve correct class inheritance in js:
function class1() {
// Constructor
}
class1.prototype = {
method: function () {
alert( " method1 " );
},
method2: function () {
alert( " method2 " );
}
}
function class2() {
// Constructor
}
// Let class2 inherit from class1
for ( var p in class1.prototype) {
class2.prototype [p] = class1.prototype[p]; //Use reflection mechanism and prototype to implement inheritance
}
// Override the method method defined in class1
class2.prototype.method = function ( ) {
alert( " class2 new method1 " );
}
// Create instances of two classes
var obj1 = new class1();
var obj2 = new class2();
function test() {
// Call the method methods of the two objects respectively
obj1.method();
obj2.method();
// Call the method2 methods of the two objects respectively
obj1.method2();
obj2.method2();
}
It can be seen from the running results that the repeated definitions in obj2 method has overridden the inherited method method, while the method2 method is unaffected. And the method method in obj1 still maintains its original definition. In this way, the correct meaning of class inheritance is achieved.In order to facilitate development, you can add a common method to each class to implement class inheritance:
// Add a static method inherit to a class to indicate inheritance from a certain class
Function.prototype.inherit = function (baseClass) {
for ( var p in baseClass.prototype) {
this .prototype[p] = baseClass.prototype[p];
}
}
function class1() {
//Constructor
}
class1.prototype = {
method: function () {
alert( " method1 " );
},
method2: function () {
alert( " method2 " );
}
}
function class2() {
// Constructor
}
/ / Let class2 inherit from class1
// for (var p in class1.prototype) {
// class2.prototype[p] = class1.prototype[p]; // Use reflection mechanism and prototype to achieve inheritance
// }
class2.inherit(class1); // Equivalent to the for loop commented out above
// Override the method defined in class1
class2 .prototype.method = function () {
alert( " class2 new method1 " );
}
// Create instances of two classes
var obj1 = new class1 ();
var obj2 = new class2();
function test() {
// Call the method methods of the two objects respectively
obj1.method();
obj2.method();
// Call method2 methods of two objects respectively
obj1.method2();
obj2.method2();
}
The above code Make the logic clearer and easier to understand. One disadvantage of inheritance implemented through this method is that when adding a class member definition in class2, you cannot directly assign a value to the prototype, but can only assign values to its attributes. For example, it cannot be:
class2.prototype={
//Member definition
}
And it can only be:
class2.prototype.propertyName=someValue;
class2.prototype.methodName=function(){
//Statement
}
It can be seen that implementing inheritance in this way still comes at the expense of a certain amount of code readability. Is there a js inheritance method that "not only can base classes directly assign objects to properties, but can also be implemented in derived classes, making the code logic clearer and better reflecting the characteristics of object-oriented languages"? The sayings in quotation marks are so tempting, keep studying.