簡體   English   中英

為什么 super function 調用自己的構造函數?

[英]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 = 4Square構造函數。 但是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM