[英]Why does changing the order of constructor function calls cause it to malfunction?
[英]Why does super function calls itself constructor?
我从 MDN 中找到了一个关于 super 的例子。 我了解到 super function 调用父类的构造函数,以便子类可以继承它的所有属性/方法。 但是,在 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 构造函数。 我的困惑在于超级 function,它有两个来自 Square 的 arguments,但 Square 是 Rectangle 的子类。 在 Square 中调用 super 并将 Rectangle 的高度和宽度传递给它,以便 Square 可以继承 Rectangle 的高度和宽度,因为 Square 正在扩展 Rectangle,这难道不合理吗?
Inheritance 自动发生,您不需要为此调用super()
。
super()
用于运行父类的构造函数。 当您调用new Square(4)
时,这会自动调用length = 4
的Square
构造函数。 但是Rectangle
构造函数需要两个参数,与Square
构造函数的参数不同。 Square
的设计是它是一个高和宽相同的矩形,所以Square
的构造函数可以将这个length
参数传递给Rectangle
来表达这个想法。
我们不能 go 反过来,因为 class 可以有许多不同的子类,并且它们各自可以与它有不同的关系。 超类无法调用所有可能的子类构造函数,因为可以任意添加子类。
在 MDN 的示例中,它调用子类的构造函数。
不,它没有。
在
Square
[...] 中调用super
是否有意义,这样Square
就可以继承Rectangle
的高度和宽度,因为Square
正在扩展Rectangle
?
这正是正在发生的事情。
…并将
Rectangle
的高度和宽度传递给它
小说明:它将一个值(正方形边长)作为高度和宽度传递给Rectangle
。
new Square
结构称为new Rectangle
结构。
Square 是从 Rectangle 派生的 class。 Square 构造函数调用父 Rectangle class 构造函数,将 Square 的长度作为 Rectangle 的宽度和高度传递。 这样做是有意义的,因为 Square是一个 Rectangle,但它是一种特殊的矩形 - 即宽度等于其高度的矩形。
请注意,Square 比 Rectangle 更具体,而 Rectangle 对 Square 一无所知。
Square 构造函数的存在是因为 Square 是 Rectangle 的特化。 正方形有长度(例如,给我画一个长度为 5 的正方形)。 它也有不同的名称(“方形”与“矩形”)。 这意味着 Square class 需要一个构造函数,以便您可以初始化 Square 的特殊之处。
因为您需要 Square 构造函数,所以 Square 构造函数必须调用 Rectangle(超级)构造函数,并且它必须在访问“this”(它在设置正方形名称时执行)或从派生构造函数返回之前调用。 这是 JavaScript 语言的要求。 如果您不调用超级构造函数,那么您的代码将失败 - 将发生 ReferenceError,如下所示:
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
如果您不需要在派生类的构造函数中进行任何特殊初始化,那么您甚至不需要在派生类 class 中声明构造函数 function。在这种情况下,JavaScript 会在创建实例时自动为您调用父类 class 构造函数derived class。但是,如果你确实在derived class中声明了一个构造函数function,即使它是空的,它也必须调用超级构造函数,否则会发生上述ReferenceError。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.