全部,在阅读此post之后,并根据它进行了一些测试。
function Shape() {
this.x = 0;
this.y = 0;
};
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.log("Shape moved.");
};
// Rectangle - subclass
function Rectangle() {
//Shape.call(this); //call super constructor.
};
Rectangle.prototype = Object.create(Shape.prototype);
var rect = new Rectangle();
alert(rect.x);
如果我对Shape.call(this);
中的代码Rectangle
进行了评论,我发现rect.x
为underfined
而不是0
。
让我感到困惑的是,我找到了Post的最佳答案:
“在javascript中,每个对象都有一个创建它的对象的秘密链接,形成一个链。当一个对象被要求提供它没有的属性时,会询问它的父对象......直到找到属性或直到达到根对象为止。“
所以我无法理解为什么rect
在原型链中找不到x
。 rect
已经从Shape
继承。如果x
中不存在rect
,则应该在他的父母中找到它。对 ?
在我的理解中。如果使用Shape.call(this);
,它只是向x
添加一个新的rect
属性,那么,这不会是重用父母原始x
的代码。它就像经典继承中的override属性一样。那就是在子类中添加一个新属性,它与基类中的属性具有相同的名称和类型。我不知道我的理解是否正确,如果没有。请纠正我。或者我错过了一些我没注意到的东西?感谢。
修改
以下是基于Thilo和Arun P Johny答案的理解。如果不对,请纠正我。
继承之前。
继承执行后。
因此x
仅属于Shape
构造的实例。感谢
答案 0 :(得分:1)
如果您不调用超级构造函数,则不会执行this.x = 0
,因此x
仍未定义。
如果您希望它出现在原型中,我认为您必须说Shape.prototype.x = 0
。
所以我无法理解为什么
rect
在原型链中找不到x
。
这是因为原型也没有x
。它只有move
。 x
被分配给构造函数中的各个实例(但仅在您调用它时)。
答案 1 :(得分:1)
Arun P Johny是对的(你应该阅读他的评论!)
试试这个:
function Shape() {
this.x = 0;
this.y = 0;
};
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.log("Shape moved.");
};
// Rectangle - subclass
function Rectangle() {
};
Rectangle.prototype = new Shape();
var rect = new Rectangle();
alert(rect.x);
您可以像在代码中那样(注释)调用Shape.call(this);
,但这样它不是“真正的”继承,因为您将无法在Rectangle中使用move()
。
但上面的代码是“新”和原型的混杂,因此非常令人困惑。我想你真正想要做的就是这样:
var Shape = {
x: 0,
y: 0,
move: function(x, y) {
this.x += x;
this.y += y;
alert("Shape moved: ["+this.x+","+this.y+"]");
}
};
var rect = Object.create(Shape);
alert(rect.x);
rect.move(2,3);
rect.move(1,1);