[英]Constructor and inheriting properties from super class in javascript
I have a question about a code demonstrating inheritance in javascript.我对在 javascript 中演示 inheritance 的代码有疑问。 The code is based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
代码基于https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
You can see live demo here: https://jsfiddle.net/gk6xar8w/3/你可以在这里看到现场演示: https://jsfiddle.net/gk6xar8w/3/
Here's the code:这是代码:
// Shape - superclass function Shape() { this.x = 1; this.y = 2; } // superclass method Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info('Shape moved.',this.x,this.y); }; // Rectangle - subclass function Rectangle() { Shape.call(this); // call super constructor. console.log("###### Inside Rectangle.constructor ######"); } // subclass extends superclass Rectangle.prototype = Object.create(Shape.prototype); //If you don't set Rectangle.prototype.constructor to Rectangle, //it will take the prototype.constructor of Shape (parent). //To avoid that, we set the prototype.constructor to Rectangle (child). Rectangle.prototype.constructor = Rectangle; var rect = new Rectangle(); console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true console.log('Is rect an instance of Shape?', rect instanceof Shape); // true rect.move(1, 2); // Outputs, 'Shape moved. 2, 4' rect.move(1, 2); // Outputs, 'Shape moved. 3, 6'
I have two questions.我有两个问题。
Firstly, I'm not sure what the effect of Rectangle.prototype.constructor = Rectangle
is.首先,我不确定
Rectangle.prototype.constructor = Rectangle
的效果是什么。 Even when I comment this line out, I still get same output.即使我注释掉这条线,我仍然得到相同的 output。 To help me understand I am logging "#### Inside Rectangle.constructor #####" inside
function Rectangle() {...}
.为了帮助我理解,我在
function Rectangle() {...}
中记录了“#### Inside Rectangle.constructor #####”。 But this logs even when I comment out Rectangle.prototype.constructor = Rectangle
.但是,即使我注释掉
Rectangle.prototype.constructor = Rectangle
,这也会记录下来。
Secondly, last two lines which both are rect.move(1, 2)
, they don't behave as I expected.其次,最后两行都是
rect.move(1, 2)
,它们的行为不像我预期的那样。 First invocation outputs 2, 4
and the second outputs 3, 6
.第一次调用输出
2, 4
和第二次输出3, 6
。
We start with this.x = 1
and this.y = 2
defined inside parent class.我们从父 class 中定义的
this.x = 1
和this.y = 2
开始。 First time we invoke rect.move(1,2)
it adds for x: 1+1=2
and y: 2+2=4
as expected.我们第一次调用
rect.move(1,2)
时,它按预期添加了 x: 1+1=2
和 y: 2+2=4
。 But second time around, it doesn't x: 2+2=4
and y: 4+4=8
as expected.但是第二次,它不像预期的那样 x:
2+2=4
和 y: 4+4=8
。 Instead it keeps the initial values of this.x = 1
and this.y = 2
and does x: 1+2=3
and y: 2+4=6
.相反,它保留
this.x = 1
和this.y = 2
的初始值并执行 x: 1+2=3
和 y: 2+4=6
。
It would be great if I can fix the code so that first invocation of rect.move(1,2)
outputs 2, 4
and second invocation ouputs 4, 8
and third outputs 8, 16
and so on.如果我可以修复代码以便第一次调用
rect.move(1,2)
输出2, 4
和第二次调用输出4, 8
和第三次输出8, 16
等等,那就太好了。
Thanks.谢谢。
As for your first question, Rectangle.prototype.constructor = Rectangle
has no effect.至于你的第一个问题,
Rectangle.prototype.constructor = Rectangle
没有效果。 That line sets the constructor of the Rectangle class but the Rectangle()
function is already the constructor, so there is no effect.该行设置了 Rectangle class 的构造函数,但
Rectangle()
function 已经是构造函数,所以没有效果。
For your second question, the move function changes the x value of the object by the x value passed into the function.对于第二个问题,移动 function 将 object 的 x 值更改为传递给 function 的 x 值。 Same goes for the y value.
y 值也是如此。 2+1=3 and 4+2=6
2+1=3 和 4+2=6
If you want the x and y values to double each time, you could use this function:如果您希望 x 和 y 值每次翻倍,您可以使用此 function:
Shape.prototype.move = function() {
this.x += this.x; // <-- uses this.x instead of x parameter
this.y += this.y; // <-- uses this.y instead of y parameter
console.info('Shape moved.',this.x,this.y);
};
I understand now.我现在知道了。
// Shape - superclass
function Shape() {
this.x = 1;
this.y = 2;
}
// superclass method
Shape.prototype.move = function() {
this.x += this.x;
this.y += this.y;
console.info('Shape moved.',this.x,this.y);
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); // call super constructor.
console.log("###### Inside Rectangle.constructor ######");
}
// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
//If you don't set Rectangle.prototype.constructor to Rectangle,
//it will take the prototype.constructor of Shape (parent).
//To avoid that, we set the prototype.constructor to Rectangle (child).
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();
console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?', rect instanceof Shape); // true
rect.move(); // Outputs, 'Shape moved.'
rect.move(); // Outputs, 'Shape moved.'
This outputs 1,2 -> 2,4 -> 4,8 ->... and requires no arguments to move().这输出 1,2 -> 2,4 -> 4,8 ->... 并且不需要 arguments 来移动()。
In the original code, this.x
and this.y
persist.在原始代码中,
this.x
和this.y
仍然存在。 Sorry for the confusion and thanks a lot.很抱歉造成混乱,非常感谢。
Here's a working code:这是一个工作代码:
// Shape - superclass
function Shape() {
this.x = 1;
this.y = 2;
}
// superclass method
Shape.prototype.move = function(a) {
this.x = this.x + a;
this.y = this.y + a;
console.info('Shape moved.',this.x,this.y);
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); // call super constructor.
console.log("###### Inside Rectangle.constructor ######");
}
// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
//If you don't set Rectangle.prototype.constructor to Rectangle,
//it will take the prototype.constructor of Shape (parent).
//To avoid that, we set the prototype.constructor to Rectangle (child).
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();
console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?', rect instanceof Shape); // true
rect.move(3); // x: 4, y: 5
rect.move(3); // x: 7, y: 8
rect.move(3); // x: 10, y: 11
Note that this.x
and this.y
are persistent.注意
this.x
和this.y
是持久的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.