Terence_ Rain 2022-01-26 11:24:55 阅读数:214
In general object-oriented languages , A special syntax is usually provided for subclasses to access the parent class , Because when we implement subclass methods, we often need the additional assistance of parent methods . under these circumstances , A subclass usually calls a method with the same name in the parent class , In order to finally complete the work .
JS Although there is no such grammar in , But it can achieve similar functions .
Next , Introduce a... Into the inheritance relationship built earlier uber attribute , And point it to the parent prototype object .
function Shape(){
}
// augment prototype
Shape.prototype.name = 'shape';
Shape.prototype.toString = function () {
var cst = this.constructor;
return cst.uber
? this.cst.uber.toString() + ', ' + this.name
: this.name;
};
function TwoDShape(){
}
//take care of inheritance
var F = function(){
};
F.prototype = Shape.prototype;
TwoDShape.prototype =new F();
TwoDShape.prototype.constructor = TwoDShape;
TwoDShape.uber = Shape.prototype;
//augment prototype
TwoDShape.prototype.name = '2D shape';
function Triangle(side, height){
this.side = side;
this.height = height;
}
//take care of inheritance
var F = function() {
};
F.prototype = TwoDShape.prototype;
Triangle.prototype = new F();
Triangle.prototype.constructor = Triangle;
Triangle.prototype.constructor = TwoDShape.prototype;
//augment prototype
Triangle.prototype.name = 'Triangle'
Triangle.prototype.getArea = function () {
return this.side * this.height / 2;
}
For this code , The new parts are :
below , Extract the previous code that implements the inheritance relationship , And encapsulated in a name called extend The methods of :
function extend(Child, Parent){
var F = function(){
};
F.prototype = Parent.prototype;
Child.prototype= new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
// Implementation inheritance
extend(TwoDShape, Shape);
extend(Triangle, TwoDShape);
Let's look at a complete example :
function extend(Child, Parent){
var F = function(){
};
F.prototype = Parent.prototype;
Child.prototype= new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
// Implementation inheritance
function Shape(){
};
Shape.prototype.name = 'Shape';
Shape.prototype.toString = function(){
return this.constructor.uber ?
this.constructor.uber.toString() + ', '+ this.name
: this.name;
};
function TwoDShape() {
};
extend(TwoDShape, Shape);
TwoDShape.prototype.name = '2D Shape';
function Triangle(side,height) {
this.side = side;
this.height = height;
}
extend(Triangle, TwoDShape);
Triangle.prototype.name = 'Triangle';
Triangle.prototype.getArea= function () {
return this.side * this.height / 2;
};
When building reusable inheritance code , We can also simply copy the properties of the parent object to the child object , Refer to the previous extend() Interface , We can create one extend2() function , This function can also accept two constructor functions as parameters , And will Parent All properties of the prototype are copied to Child The prototype of the , This includes methods . Because a method is also an attribute of a function type .
function extend2(Child, Parent){
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p){
c[i] = p[i];
}
c.uber = p;
}
such , Through a simple loop through all the attributes accepted by the function . In the previous example , If the child object mainly accesses the method of the parent object , Can be set by uber Property to implement . And the situation here is different from before , Because we have finished the research on Child Extend the prototype , No need to reset Child.prototype.constructor attribute , Because it won't be completely covered anymore , So here it is ,constructor The value pointed to by the property is correct .
This method applies only to objects that contain basic types , All object types ( Functions and arrays ) Are not replicable , Because then they only support reference passing .
Here are two constructor functions Shape() and TwoDShape(). among ,Shape() The prototype of contains a basic type attribute name, And a non basic type attribute toString Method :
var Shape = function(){
};
var TwoDShape = function(){
};
Shape.prototype.name = 'shape';
Shape.prototype.toString = function(){
return this.uber
? this.uber.toString() + ', ' + this.name
: this.name;
};
If you pass extend() Method to implement inheritance ,name The attribute is neither TwoDShape() Properties of the sample , Nor will it become an attribute of its prototype object , However, child objects can still access properties through inheritance .
If inheritance is through extend2 To achieve ,TwoDShape You will copy it from your prototype to get your own name attribute . Again , It will also copy its own toString Method , But this is just a function reference , The function itself is not created again .
copyright:author[Terence_ Rain],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/01/202201261124514724.html