简体   繁体   English

javascript 中的超级 class 的构造函数和继承属性

[英]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 = 1this.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 = 1this.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.xthis.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.xthis.y是持久的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM