function Shape() {
this.name = "none";
}
function Rect () {
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
};
Run Code Online (Sandbox Code Playgroud)
如果Shape的所有属性都可用于Rect,那么写入是正确的
Rect.prototype = Shape;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,每个实例Rect(i.e. Object.create(Rect))都会从Shape对象中获取一个单独的名称.
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}});
Run Code Online (Sandbox Code Playgroud)
您还没有任何自定义属性Shape.prototype,但是,设置它会使以下工作:
var r = new Rect();
r instanceof Shape; // true
Run Code Online (Sandbox Code Playgroud)
您还必须在构造函数中调用超级构造函数(Shape)Rect,设置this为新实例:
function Rect () {
Shape.call(this);
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
}
Run Code Online (Sandbox Code Playgroud)
Shape.call(this);是name分配给我们的新Rect 实例的时刻.
如果您来自Java或其他面向类的OO语言,这与super();在子构造函数中调用基本相同.
以上所有内容正是新ES6 class语法在内部所做的.
class Rect extends Shape {
constructor() {
super();
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
55 次 |
| 最近记录: |