'Why here in Protoypical inheritance Child class method is not called instead of Parent Class Method?
I have a Shape as parent class, and Circle as a child class. Using prototypical inheritance in Javascript, I have overridden the parent class duplicate method.
When I run the following code, calling the duplicate method on the child object (circle), instead of executing the child class method, it is calling the parent class (Shape) method. And when I comment out the parent class duplicate method, it is calling the child class method. This is the opposite of what I expected. I thought it should give precedence to the child method, so I don't understand what I am doing wrong....
function Shape(color) {
this.color = color;
this.duplicate = function () {
console.log("This is shape duplicate method");
};
}
function Circle(radius, color) {
Shape.call(this, color);
this.radius = radius;
this.draw = function () {
console.log("This is Circle draw method");
};
}
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
Circle.prototype.duplicate = function () {
console.log("This is biggg cirlce after duplication");
};
const circle = new Circle(4, "pink");
console.log("Radius of Circle is: ", circle.radius);
console.log("Color of Circle is: ", circle.color);
circle.duplicate();
circle.draw();
After running above code I got as output:
Radius of Circle is: 4
Color of Circle is: pink
This is shape duplicate method
This is Circle draw method
Solution 1:[1]
When you perform circle.duplicate(), JS first searches for duplicate on the circle object itself, and if it can't find it, it then looks for it on the circle's prototype, if it can't find it there either, it searches for it on the prototype's prototype, and so on until it is able to find the duplicate property.
In the case of your circle object, you have two versions of the duplicate function, one as an own property on the circle instance itself and one of the circle's prototype object. The duplicate() function you want to invoke is located on the prototype, but you can't "reach" it, as the duplicate function on the circle itself gets invoked instead.
The reason why your circle instance has a duplicate function is due to calling your parent constructor when you perform Shape.call(this, color);, which calls your Shape function that then adds the parent duplicate() function to your circle instance (this):
this.duplicate = function () {
console.log("This is shape duplicate method");
};
This function takes precedence over the function on your prototype, as it is on the circle object itself.
Typically, you would define functions on the prototype rather than on the instance itself. Currently, your parent creates a new function every time a new parent instance is created. Instead, you can add your duplicate() function to your parent's prototype to avoid creating a new function object each time your create a Parent object. Moreover, adding it to the prototype avoids you adding a duplicate() method directly to your circle object when you call the parent constructor from your child Cricle constructor function, which you won't be adding duplicate to your the circle instance itself, which will allow circle.duplicate() to call the duplicate method defined on the circle's prototype:
function Shape(color) {
this.color = color;
}
Shape.prototype.duplicate = function () {
console.log("This is shape duplicate method");
};
function Circle(radius, color) {
Shape.call(this, color);
this.radius = radius;
}
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
// Override
Circle.prototype.duplicate = function () {
console.log("This is biggg cirlce after duplication");
};
Circle.prototype.draw = function () { // move the draw function to the prototype so we only create "one" function that can be shared amongst all circle objects (saves on memory)
console.log("This is Circle draw method");
};
const circle = new Circle(4, "pink");
console.log("Radius of Circle is: ", circle.radius);
console.log("Color of Circle is: ", circle.color);
circle.duplicate(); // This is biggg cirlce after duplication
circle.draw();
On a side note, I see that you're using newer (well, not so new these days) features of JS such as const, but are still working with old function constructors. These days JS has its own class declarations which implement and handles a lot of the overhead of the above code for you. You can rewrite the above-using classes like so:
class Shape {
constructor(color) {
this.color = color;
}
duplicate() { // methods defind in a `class` automatically get added to the object's prototype
console.log("This is shape duplicate method");
};
}
class Circle extends Shape { // `extends` is how we perform inheritance using classes
constructor(radius, color) {
super(color); // similar to Shape.call(this, color)
this.radius = radius;
}
draw() {
console.log("This is Circle draw method");
};
duplicate() {
console.log("This is biggg cirlce after duplication");
};
}
const circle = new Circle(4, "pink");
console.log(circle);
console.log("Radius of Circle is: ", circle.radius);
console.log("Color of Circle is: ", circle.color);
circle.duplicate(); // This is biggg cirlce after duplication
circle.draw();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
