简体   繁体   English

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

[英]Why does super function calls itself constructor?

I found an example from MDN about super.我从 MDN 中找到了一个关于 super 的例子。 I learned that super function calls parent's constructor so that the subclass can inherit all the properties/methods from it.我了解到 super function 调用父类的构造函数,以便子类可以继承它的所有属性/方法。 However, in the example from MDn, it calls the subclass's constructor.但是,在 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>

So we have a Square constructor which extends from Rectangle.所以我们有一个从 Rectangle 扩展而来的 Square 构造函数。 My confusion is at the super function which has two arguments from Square but Square is the subclass of Rectangle.我的困惑在于超级 function,它有两个来自 Square 的 arguments,但 Square 是 Rectangle 的子类。 Wouldn't it make sense to call super within Square and pass height and width from Rectangle to it so that Square can inherit the height and width from Rectangle since Square is extending Rectangle?在 Square 中调用 super 并将 Rectangle 的高度和宽度传递给它,以便 Square 可以继承 Rectangle 的高度和宽度,因为 Square 正在扩展 Rectangle,这难道不合理吗?

Inheritance happens automatically, you don't need to call super() for this. Inheritance 自动发生,您不需要为此调用super()

super() is used to run the parent class's constructor. super()用于运行父类的构造函数。 When you call new Square(4) , this calls the Square constructor automatically with length = 4 .当您调用new Square(4)时,这会自动调用length = 4Square构造函数。 But the Rectangle constructor requires two parameters, not the same parameters as the Square constructor.但是Rectangle构造函数需要两个参数,与Square构造函数的参数不同。 The design of Square is that it's a rectangle whose height and width are the same, so the Square constructor can pass this length parameter to Rectangle to express this idea. Square的设计是它是一个高和宽相同的矩形,所以Square的构造函数可以将这个length参数传递给Rectangle来表达这个想法。

We can't go the other way, because a class can have many different subclasses, and they can each have different relationships with it.我们不能 go 反过来,因为 class 可以有许多不同的子类,并且它们各自可以与它有不同的关系。 There's no way for the superclass to call all possible subclass constructors, since subclasses can be added arbitrarily.超类无法调用所有可能的子类构造函数,因为可以任意添加子类。

in the example from MDN, it calls the subclass's constructor.在 MDN 的示例中,它调用子类的构造函数。

No it doesn't.不,它没有。

Wouldn't it make sense to call super within Square […] so that Square can inherit the height and width from Rectangle since Square is extending Rectangle ?Square [...] 中调用super是否有意义,这样Square就可以继承Rectangle的高度和宽度,因为Square正在扩展Rectangle

That's exactly what's happening.这正是正在发生的事情。

… and pass height and width from Rectangle to it …并将Rectangle的高度和宽度传递给它

small clarification: it's passing a value (the square side length) as height and width to Rectangle .小说明:它将一个值(正方形边长)作为高度和宽度传递给Rectangle

The new Square construction calls the new Rectangle construction. new Square结构称为new Rectangle结构。

Square is a class derived from Rectangle. Square 是从 Rectangle 派生的 class。 The Square constructor calls the parent Rectangle class constructor passing the Square's length as both the Rectangle's width and height. Square 构造函数调用父 Rectangle class 构造函数,将 Square 的长度作为 Rectangle 的宽度高度传递。 It makes sense to do this because a Square is a Rectangle, but it's a specific kind of rectangle - namely one whose width equals its height.这样做是有意义的,因为 Square一个 Rectangle,但它是一种特殊的矩形 - 即宽度等于其高度的矩形。

Note that Square is more specific than Rectangle and Rectangle knows nothing about Square.请注意,Square 比 Rectangle 更具体,而 Rectangle 对 Square 一无所知。

The Square constructor exists because a Square is a specialization of a Rectangle. Square 构造函数的存在是因为 Square 是 Rectangle 的特化。 A Square has length (eg draw me a square of length 5).正方形有长度(例如,给我画一个长度为 5 的正方形)。 It also has a different name ('Square' vs. 'Rectangle').它也有不同的名称(“方形”与“矩形”)。 That means that the Square class needs a constructor, so that you can initialize the things that are special about a Square.这意味着 Square class 需要一个构造函数,以便您可以初始化 Square 的特殊之处。

Because you need a Square constructor, that Square constructor must call the Rectangle (super) constructor and it must do so before accessing 'this' (which it does when it sets the square's name) or returning from the derived constructor.因为您需要 Square 构造函数,所以 Square 构造函数必须调用 Rectangle(超级)构造函数,并且它必须在访问“this”(它在设置正方形名称时执行)或从派生构造函数返回之前调用。 This is a requirement of the JavaScript language.这是 JavaScript 语言的要求。 If you don't call the super constructor then your code will fail - a ReferenceError will happen, like so:如果您不调用超级构造函数,那么您的代码将失败 - 将发生 ReferenceError,如下所示:

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

If you did not need to do any special initialization in a derived class's constructor then you would not even need to declare a constructor function in the derived class. In this case, JavaScript would automatically call the parent class constructor for you when creating an instance of the derived class. But, if you did declare a constructor function in the derived class, even if it was empty, it would have to call the super constructor, otherwise the aforementioned ReferenceError would happen.如果您不需要在派生类的构造函数中进行任何特殊初始化,那么您甚至不需要在派生类 class 中声明构造函数 function。在这种情况下,JavaScript 会在创建实例时自动为您调用父类 class 构造函数derived class。但是,如果你确实在derived class中声明了一个构造函数function,即使它是空的,它也必须调用超级构造函数,否则会发生上述ReferenceError。

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

相关问题 为什么改变构造函数调用的顺序会导致它发生故障? - Why does changing the order of constructor function calls cause it to malfunction? 骨干构造器自称 - Backbone constructor calls itself 为什么 Promise 构造函数需要一个在完成时调用“resolve”的函数,而“then”却不需要——而是返回一个值? - Why does the Promise constructor require a function that calls 'resolve' when complete, but 'then' does not - it returns a value instead? ES6 super()在构造函数中实际做了什么? - ES6 What does super() actually do in constructor function? 为什么在超级构造函数的调用中不能在箭头函数中使用“ this”? - Why can't I use “this” in an arrow function in a call to the super constructor? 调用自身的异步 function - Async function that calls itself 为什么原型的构造函数会返回自身? - Why does prototype's constructor refer back to itself? 为什么 object __proto__ 不是构造函数 function 本身? - Why isn't the object __proto__ the constructor function itself? 为什么jQuery将自己包装在一个函数中? - Why does jQuery wrap itself in a function? 为什么此javascript函数自己执行 - Why does this javascript function executes by itself
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM