[英]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.