iT邦幫忙

2025 iThome 鐵人賽

DAY 6
0
Modern Web

JavaScript 進階修煉與一些 React ——離開初階工程師新手村的頭30天系列 第 6

離開 JS 初階工程師新手村的 Day 06|繼承之力:super() 的英雄召喚

  • 分享至 

  • xImage
  •  
💡 本篇主題與重點字:**super**

從原型鏈到 class

昨天提到 JavaScript 是一門基於原型繼承的語言,不同於傳統物件導向語言的類別繼承,透過建構函式和原型鏈來實現繼承。

https://ithelp.ithome.com.tw/upload/images/20250914/20168365jHcVXHWRKP.png

這種寫法雖然功能完整,但語法較為冗長且容易出錯。ES6 引入了 class 語法糖,讓繼承變得更加直觀,而 super 關鍵字正是這套語法的核心機制之一!
https://ithelp.ithome.com.tw/upload/images/20250917/20168365rngQFjvTLA.png

語法糖: 電腦語言中添加的某種語法,這種語法對語言的功能沒有影響,但是更方便程式設計師使用。 —— 維基

當我們在 JavaScript 的 class 語法中使用 super 時,實際上是對父類別(superclass)的一種訪問方式,底層仍然依賴原型鏈與函式綁定機制。讓我們看看上面的程式碼在底層是如何運作的:

Class Animal 的實際轉換
https://ithelp.ithome.com.tw/upload/images/20250917/20168365NaDH2TRjqT.png

Class Animal 實際上變成了一個 constructor,然後再把 speak 方法加到 Animal.prototype 上。

Class Dog 的實際轉換
https://ithelp.ithome.com.tw/upload/images/20250917/20168365XHaCZiVYB4.png

Class Dog 也先變成一個 constructor,然後如昨天的步驟建立原型鏈繼承關係,再把新的方法 bark 添加到 Dog.prototype。

這樣的轉換讓我們理解到:

  • Dog.prototype.__proto__ === Animal.prototype 為真
  • Dog.__proto__ === Animal(用於靜態方法的繼承)

原理

在 ES6 語法中,super(name) 看起來像是直接呼叫父類的建構函式,但實際的工作原理其實誠如昨天所說的 call。當你在子類的 constructor 中使用 super() 時,JavaScript 引擎會:

  1. 暫時將 this 的綁定設定為正在創建的新實例
  2. 呼叫父類的建構函數,並將這個 this 傳入
  3. 讓父類的建構函數在子類實例的上下文中執行

這個過程本質上就是 Animal.call(this, name) 的等價物。


所有的方法調用,因為語法糖畢竟不改變邏輯,所以最終實際上的底層實作都會回到昨天的原理:當在一個方法內使用 super.method() 時,JavaScript 引擎會先找出這個方法的定義位置的原型,然後沿著原型鏈向上尋找該方法並執行(或是直到找不到)。

用法

1. 在 constructor 中呼叫父類別的建構函數
https://ithelp.ithome.com.tw/upload/images/20250917/20168365MF6BKSUbvZ.png

  • super(name) 呼叫的是 Animal 的建構函式,等同於 Animal.call(this, name)
  • 在子類別的 constructor 中必須先呼叫 super(),否則會出現錯誤,因為 this 還沒被初始化

2. 呼叫父類別的實例方法

https://ithelp.ithome.com.tw/upload/images/20250917/201683651aJJyVy4dM.png

這樣會得到

Fido makes a noise.
Fido barks.

super 與 this

需要特別注意的是,super.method() 中的 this 仍然指向當前實例,而不是父類別,我們可以回顧前幾天的 this 是誰,因為 this 是動態傳入 super() 底層機制的 .call(this) ,因此指向的對象是子類別。

https://ithelp.ithome.com.tw/upload/images/20250917/20168365o50IHEK5mg.png

ES5 vs ES6 語法比較

比較項目 ES5 傳統原型繼承 ES6 class 語法
建構函式定義 使用 function 使用 class
屬性繼承 Parent.call(this) super()
方法繼承 Object.create() 設定原型鏈 extends 自動建立
原型鏈設定 手動設定 prototype 語法糖,自動處理
可讀性 較複雜,容易出錯 理解上會更貼近 OOP
實質本質 基於 prototype chain 基於 prototype chain

ES6 語法的優勢

  • 自動的 constructor 修正Dog.prototype.constructor = Dog 這步驟自動完成
  • 更清晰的繼承語義extends 讓繼承關係一目了然
  • super 關鍵字的便利性:提供更直觀的父類方法呼叫方式
  • 保持動態特性:仍保有原型繼承的動態特性

一般來說,現在已經不會看到有 ES5 的寫法了,但為了更好地掌握 JS 本質以避免一些奇怪的 bug,知道這些語法糖底下的基礎邏輯與如何解析運行,還是蠻重要的!!


上一篇
離開 JS 初階工程師新手村的 Day 05|血統傳承:原型鏈 Prototype Chain
下一篇
離開 JS 初階工程師新手村的 Day 07|新武器庫:ES6+ 語法
系列文
JavaScript 進階修煉與一些 React ——離開初階工程師新手村的頭30天10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言