为什么超函数调用自己的构造函数?



我在MDN上找到了一个关于super的例子。我了解到,超函数调用父的构造函数,以便子类可以继承所有的属性/方法。然而,在MDn的例子中,它调用了子类的构造函数。

<script>
class Rectangle {
constructor(height, width) {
this.name = 'Rectangle';
this.height = height;
this.width = width;
}
}
class Square extends Rectangle {
constructor(length) {
super(length, length);
this.name = 'Square';
}
}
let a = new Square(4);
console.log(JSON.stringify(a));
console.log(a.height);
</script>

我们有一个从Rectangle扩展而来的Square构造函数。我的困惑是在超级函数,它有两个来自Square的参数,但Square是矩形的子类。在Square内部调用super并将height和width从Rectangle传递给它,这样Square就可以从Rectangle继承height和width了,因为Square是在扩展Rectangle?

Square是矩形的派生类。Square构造函数调用父类Rectangle构造函数,将Square的长度作为Rectangle的宽度和高度传递。这样做是有意义的,因为正方形矩形,但它是一种特定类型的矩形——即宽度等于高度的矩形。

注意,Square比Rectangle更具体,而Rectangle对Square一无所知。

Square构造函数的存在是因为Square是Rectangle的专门化。正方形有长度(例如,给我画一个长度为5的正方形)。它也有不同的名称("正方形"vs"正方形")。"矩形")。这意味着Square类需要一个构造函数,这样你就可以初始化关于Square的特殊内容。

因为你需要一个Square构造函数,所以这个Square构造函数必须调用Rectangle(超)构造函数,并且必须在访问'this'(当它设置Square的名称时)或从派生构造函数返回之前调用。这是JavaScript语言的要求。如果你不调用超级构造函数,那么你的代码就会失败——会发生ReferenceError,如下所示:

ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

如果你不需要在派生类的构造函数中做任何特殊的初始化,那么你甚至不需要在派生类中声明构造函数。在这种情况下,当创建派生类的实例时,JavaScript将自动为您调用父类构造函数。但是,如果你做了声明派生类的构造函数,即使它是空的,它会叫超级构造函数,否则会发生上述ReferenceError。

继承是自动发生的,您不需要为此调用super()

super()用于运行父类的构造函数。当您调用new Square(4)时,这将自动调用length = 4Square构造函数。但是Rectangle构造函数需要两个参数,与Square构造函数不同。Square的设计是一个矩形,它的高和宽是相同的,所以Square的构造函数可以把这个length参数传递给Rectangle来表达这个想法。

我们不能反其道而行,因为一个类可以有许多不同的子类,每个子类都可以与它有不同的关系。超类没有办法调用所有可能的子类构造函数,因为子类可以任意添加。

在MDN的例子中,它调用子类的构造函数。

不,它没有。

Square中调用super不是很有意义吗[…]这样Square就可以继承Rectangle的高度和宽度,因为Square正在扩展Rectangle?

这是发生了什么。

…并将高度和宽度从Rectangle传递给它

小澄清:它传递了一个值(正方形边长)作为高度和宽度Rectangle.

new Square构造调用new Rectangle构造。

最新更新