function Shape() {
this.name = "none";
}
function Rect () {
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
};
如果Shape的所有属性都可用于Rect,那么写
是正确的Rect.prototype = Shape;
在这种情况下,Rect(i.e. Object.create(Rect))
的每个实例都会从Shape对象中获取一个单独的名称。
答案 0 :(得分:6)
Rect.prototype = Shape;
绝对不正确。 Rect
的每个实例都具有与函数 Shape
相同的属性。这包括每个函数都有的方法,如.call
和.apply
。
但是,即使Rect.prototype = new Shape;
如其他答案中所建议的那样也不是一个好的解决方案。虽然这会将name
添加到Rect
的每个实例,但每个实例都会共享相同的name
属性。但name
是特定于实例的属性,它不属于原型。原型链应该只包含应该由每个实例共享的属性(值)。
那么,该怎么办?
将Shape.prototype
添加到Rect
个实例的原型链中:
Rect.prototype = Object.create(Shape.prototype, {constructor: {value: Rect}});
您在Shape.prototype
上没有任何自定义属性,但是,设置此属性可以完成以下工作:
var r = new Rect();
r instanceof Shape; // true
您还必须在Shape
构造函数中调用超级构造函数(Rect
),并将this
设置为新实例:
function Rect () {
Shape.call(this);
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
}
Shape.call(this);
是name
分配给我们的新Rect
实例的时刻。
如果您来自Java或其他面向类的OO语言,这与在子构造函数中调用super();
基本相同。
以上所有内容正是新ES6 class
语法在内部的作用。
class Rect extends Shape {
constructor() {
super();
// ...
}
}
答案 1 :(得分:0)
你必须写下以下内容。
Rect.prototype = new Shape();
这将为Shape
创建一个新对象,然后将其指定为Rect
的原型。您不能将函数指定为原型。