Rect.prototype = Shape;
is definitely incorrect. Every instance of Rect
would have the same properties as the function Shape
. That includes methods that every function has, like .call
and .apply
.
But even Rect.prototype = new Shape;
as suggested in the other answer is not a good solution. While this would add name
to every instance of Rect
, every instance would share the same name
property. But name
is an instance specific property, it does not belong on the prototype. The prototype chain should only hold properties (values) that are supposed to be shared by every instance.
So, how to do it?
Add Shape.prototype
to the prototype chain of Rect
instances:
Rect.prototype = Object.create(Shape.prototype, {constructor: {value: Rect}});
You don't have any custom properties on Shape.prototype
yet, however, setting this up makes the following work:
var r = new Rect();
r instanceof Shape; // true
You also have to call the super constructor (Shape
) inside the Rect
constructor, setting this
to the new instance:
function Rect () {
Shape.call(this);
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
}
Shape.call(this);
is the moment where name
is assigned to our new Rect
instance.
If you come from Java or another class-oriented OO language, this is basically the same as calling super();
in the child constructor.
All of the above is exactly what the new ES6 class
syntax does internally.
class Rect extends Shape {
constructor() {
super();
// ...
}
}