'How to properly set prototype?
I'm practicing an exercise in a book called Object-Oriented JavaScript.
The exercise in chapter 5 contains the following 4 questions:
- Create an object called shape that has the type property and a
getType()
method.- Define a
Triangle()
constructor function whose prototype is shape. Objects created withTriangle()
should have three own properties—a, b, and c, representing the lengths of the sides of a triangle.- Add a new method to the prototype called
getPerimeter()
.- Test your implementation with the following code:
.
var t = new Triangle(1, 2, 3); t.constructor === Triangle; // true shape.isPrototypeOf(t); // true t.getPerimeter(); // 6 t.getType(); // "triangle"
And this is my solution for the above questions:
var shape = {
type: 'triangle',
getType: function() {
return this.type;
}
};
function Triangle(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
}
Triangle.prototype = shape; // Maybe something goes wrong here
Triangle.prototype.getPerimeter = function() {
return this.a + this.b + this.c;
}
// ======================================================
var t = new Triangle(1, 2, 3);
console.log(t.constructor === Triangle); // false
console.log(shape.isPrototypeOf(t)); // true
console.log(t.getPerimeter()); // 6
console.log(t.getType()); // triangle
Why does console.log(t.constructor === Triangle);
output false
as the result?
I've tried removing console.log(t.constructor === Triangle);
, which makes t.constructor === Triangle
equals true
, but results in TypeError: t.getType is not a function
error.
How can I make my execution results the same as the answers provided by this book?
Solution 1:[1]
Adding
Triangle.prototype.constructor = Triangle;
after
Triangle.prototype = shape;
solves my problem.
In chapter 6 page 173, the book says
Overwriting the prototype has side effects on the constructor property. Therefore, it's a good idea to reset the constructor after inheriting
Solution 2:[2]
Shape = {
type: 'Shape',
getType: function (){ return this.type;}
}
function Triangle( a, b, c){
this.a = a;
this.b = b;
this.c = c;
this.type = 'Triangle';
}
Triangle.prototype = Shape;
Triangle.prototype.constructor = Triangle;
Triangle.prototype.getPerimeter = function (){
console.log('Get Perimeter');
return this.a + this.b + this.c;
}
var t = new Triangle(1,2,3);
console.log(t.constructor === Triangle);
console.log(Shape.isPrototypeOf(t));
console.log(t.getPerimeter());
console.log(t.getType());
Assign Shap object to Triangle.prototype and then overwrite constructor with Triangle will solve the problem.
Solution 3:[3]
function Shape() {
type = "Shape";
}
Shape.prototype.getType = function() {
return "Mi tipo es " + this.type;
}
function Triangle(a, b, c) {
Shape.call(this)
this.a = a;
this.b = b;
this.c = c;
this.type = "Triangle";
}
Triangle.prototype = Object.create(Shape.prototype);
Triangle.prototype.constructor = Triangle;
Triangle.prototype.getPerimeter = function() {
return this.a + this.b + this.c;
}
var t = new Triangle(1, 2, 3);
console.log(t instanceof Triangle);
console.log(Shape.prototype.isPrototypeOf(t));
t.getPerimeter();
t.getType();
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 | |
Solution 2 | Senthil |
Solution 3 | Cristina MurguĂa |