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(即 Object.create(Rect))
的每个实例都会从 Shape 对象中获取单独的名称。
最佳答案
Rect.prototype = Shape;
肯定是不正确的。 Rect
的每个实例都将具有与函数 Shape
相同的属性。其中包括每个函数都有的方法,例如 .call
和 .apply
。
但即使如其他答案中所建议的 Rect.prototype = new Shape;
也不是一个好的解决方案。虽然这会将 name
添加到 Rect
的每个实例,但每个实例都将共享相同的 name
属性。但是 name
是一个特定于实例的属性,它不属于原型(prototype)。原型(prototype)链应该只保存应该由每个实例共享的属性(值)。
那么,该怎么做呢?
将Shape.prototype
添加到Rect
实例的原型(prototype)链中:
Rect.prototype = Object.create(Shape.prototype, {constructor: {value: Rect}});
您在 Shape.prototype
上还没有任何自定义属性,但是,设置此属性可以实现以下工作:
var r = new Rect();
r instanceof Shape; // true
您还必须在 Rect
构造函数内调用 super 构造函数 (Shape
),将 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();
// ...
}
}
关于javascript 继承和唯一实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25221279/