Inheritance in JavaScript (3)

Terence_ Rain 2022-01-26 11:24:55 阅读数:214

inheritance javascript

1.uber- How child objects access parent objects

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 :

  • take uner Property to point to a reference to its parent prototype
  • Yes toString() Method has been updated
    Before that ,toString All you do is return this.name It's just the content of . Now an additional task has been added , That is, check whether there is... In the object this.constructor.uber attribute , If there is , Just call the... Of this property first toString Method . because this.constructor Itself is a function , and this.constructor.uber Is a reference to the parent prototype of the current object . So when we call Triangle The entity's toString When the method is used , All on its prototype chain toString Will be called .

2. Encapsulate the inherited part into a function

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;
};

3. Property copy

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