首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果我在javascript中子类化时没有正确设置构造函数,会出什么问题?

如果我在javascript中子类化时没有正确设置构造函数,会出什么问题?
EN

Stack Overflow用户
提问于 2014-01-17 12:35:37
回答 3查看 212关注 0票数 3

我最近在学习javascript中基于原型的面向对象编程。在阅读了大量用javascript解释原型机制的网站后,我决定使用Mozilla的这种方法

以下是Mozilla的一些代码片段:

代码语言:javascript
运行
复制
// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

rect instanceof Rectangle // true.
rect instanceof Shape // true.

rect.move(1, 1); // Outputs, "Shape moved."

我知道Rectangle.prototype = Object.create(Shape.prototype);会正确地设置原型链,这样Rectangle的实例就会继承Shape的方法。

但是Rectangle.prototype.constructor = Rectangle;这一行有点让人迷惑。

this website我知道,当我们创建像function MyClass(){}这样的新对象时,javascript会将其原型设置为空对象,并且MyClass.prototype.constructor将指向MyClass。因此Rectangle.prototype.constructor = Rectangle;将修复断开的链接,因为Object.create(Shape.prototype).constructor仍然指向Shape

但是如果我删除这一行,我仍然可以运行下面的代码而不会出现问题。我只是好奇是否有任何构造函数属性的用例?如果我只是让它指向超类,会出什么问题?

EN

回答 3

Stack Overflow用户

发布于 2014-01-17 12:41:13

以这种方式设置属性将使其成为可枚举的( for in语句将列出构造函数属性)。

代码语言:javascript
运行
复制
var rec = new Rectangle();
'constructor' in rec; //true

您应该使用Object.defineProperty或将第二个参数传递给Object.create。

代码语言:javascript
运行
复制
Rectangle.prototype = Object.create(Shape.prototype, {constructor: {enumerable: false }});

var rec = new Rectangle();
'constructor' in rec; //

有关构造函数属性的更多信息,请参阅此线程:

https://stackoverflow.com/a/4013295

票数 3
EN

Stack Overflow用户

发布于 2014-01-17 14:00:27

在您的代码中,这没有任何区别,因为您仍然使用Rectangle构造函数(显式地使用其名称:var rect = new Rectangle();)创建对象。

唯一的区别是,当你丢失了对object构造函数的引用,或者你根本不知道它是什么:

代码语言:javascript
运行
复制
// Shape - superclass
function Shape() {
    this.x = 1;
    this.y = 1;
}

// superclass method
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info(this.x + " " + this.y);
};

// Rectangle - subclass
function Rectangle() {
    Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
//Rectangle.prototype.constructor = Rectangle;

console.info("RECT");
var rect = new Rectangle;
console.info(rect);
console.info(rect instanceof Rectangle);
console.info(rect instanceof Shape);
//console.info(rect instanceof Square); TypeError - Square must be a function, but is still not initialized
rect.move(1, 1);

console.info("RECT2");
var rect2 = new rect.constructor();
console.info(rect2);
console.info(rect2 instanceof Rectangle);
console.info(rect2 instanceof Shape);
// console.info(rect2 instanceof Square); TypeError - Square must be a function, but is still not initialized
rect2.move(1, 1);

console.info("RECT3");
var Square = rect.constructor;
Square.prototype.move = function(x, y) { // just to make it different
    this.x *= x;
    this.y *= y;
    console.info(this.x + " " + this.y);
}

var rect3 = new Square();
console.info(rect3);
console.info(rect3 instanceof Rectangle);
console.info(rect3 instanceof Shape);
console.info(rect3 instanceof Square);
rect3.move(4, 4);

我在设置构造函数时注释掉了这一行。取消注释以查看输出中的差异。我还添加了另一种使用构造函数属性的方法--另一个继承示例(基于ShapeSquare,但具有不同的move方法)。

因此,如果您不修复这个链接,在我展示的例子中,您将使用Shape构造函数,并且创建相同类型的对象将变得不可能。rect是这两种类型的,但rect2不再是。

因此,假设即使您不需要它,将此链接修复到正确的构造函数也是一个非常好的实践,因为将来使用您的代码的人可能需要它。

编辑:

constructor属性不会影响object本身的任何内容。它是在创建object后设置的,用于将reference保存到创建objectfunction中。如果你将来需要它,那么有一个正确的版本是有意义的。我看不到任何其他问题。

票数 2
EN

Stack Overflow用户

发布于 2014-01-17 14:00:05

如果对象在其继承链中属于指定的对象类型,则instanceOf将返回true。它与构造函数属性无关。

如果我们想在创建对象时初始化属性或执行默认代码,我们可以使用构造函数属性。

例如,在您的示例中,如果我们想要创建始终为红色的矩形,可以使用Rectangle的构造函数,如下所示:

代码语言:javascript
运行
复制
function Rectangle() {
  Shape.call(this); // call super constructor.
  this.color = "red";
}

希望这能清除你的疑问。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21177995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档