Ways of inheritance
ECMAScript has more than one way to implement inheritance. This is because the inheritance mechanism in JavaScript is not explicitly specified but implemented through imitation. This means that not all inheritance details are entirely handled by the interpreter. As the developer, you have the right to decide the inheritance method that works best for you. The most primitive inheritance implementation method is object impersonation. This method will be introduced below.
Object impersonation
The core of object impersonation to implement inheritance actually relies on using the this keyword in a function environment. The principle is as follows: the constructor uses the this keyword to assign values to all properties and methods (that is, using the constructor method of class declaration). Because a constructor is just a function, you can make the ClassA constructor a method of ClassB and then call it. ClassB will receive the properties and methods defined in the constructor of ClassA. For example, define ClassA and ClassB in the following way:
function ClassA(sColor) {
this.color = sColor;
this.sayColor = function () {
alert(this.color);
};
}
function ClassB(sColor) {
}
The keyword this refers to the object currently created by the constructor. But in this method, this points to the object it belongs to. The principle is to use ClassA as a regular function to establish the inheritance mechanism, rather than as a constructor. The inheritance mechanism can be implemented by using the constructor ClassB as follows:
function ClassB (sColor) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
}
In this code, ClassA is assigned the method newMethod (remember, the function name is just a pointer to it). The method is then called, passing it the parameter sColor of the ClassB constructor. The last line of code removes the reference to ClassA so that it can no longer be called in the future.
All new properties and new methods must be defined after removing the line of code for the new method. Otherwise, the relevant properties and methods of the super class may be overridden:
function ClassB(sColor, sName) {
this.newMethod = ClassA;
this.newMethod(sColor);
delete this.newMethod;
this.name = sName;
this.sayName = function () {
alert(this.name);
};
}
To prove that the previous code is valid, you can run the following example:
var objA = new ClassA("blue");
var objB = new ClassB("red", "John");
objA.sayColor(); //Output "blue"
objB.sayColor(); //Output "red"
objB.sayName(); //Output "John"
Object impersonation can achieve multiple inheritance
Interestingly, object impersonation can support multiple inheritance. For example, if there are two classes ClassX and ClassY, and ClassZ wants to inherit these two classes, you can use the following code:
function ClassZ() {
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
}
There is a drawback here, if there are two classes ClassX For properties or methods with the same name as ClassY, ClassY has high priority. Because it inherits from the later class. Apart from this minor problem, it is easy to implement multiple inheritance mechanisms using object impersonation.
Due to the popularity of this inheritance method, the third version of ECMAScript added two methods to the Function object, namely call() and apply(). Later, many derived methods for implementing inheritance were actually implemented based on call() and apply().