1. 物件導向與 new 關鍵字
JavaScript 是基於 原型 (Prototype) 的物件導向語言,而非典型的 類別 (Class) 為基礎的語言。但 ES6 之後,JavaScript 引入了 class 語法,使其更接近傳統的物件導向語言,如 Java 或 C++。
在 JavaScript 中,new 關鍵字用於建立物件,並且會執行以下步驟:
- 建立一個新的空物件。
- 設定該物件的
__proto__指向建構函式 (Constructor) 的prototype。 - 執行建構函式內的程式碼,並將
this綁定到新建立的物件。 - 如果建構函式沒有明確返回物件,則回傳該新物件。
範例:
function Person(name, age) { |
2. __proto__ vs prototype
在 JavaScript 中,__proto__ 和 prototype 是兩個不同的概念。
prototype
prototype 是建構函式的一個屬性,它是一個物件,當我們使用 new 建立物件時,該物件的 __proto__ 會指向 prototype。
範例:
function Animal(name) { |
__proto__
__proto__ 是物件的內部屬性,指向該物件的原型,即 prototype。
範例:
console.log(dog.__proto__); // Animal.prototype |
關鍵點整理:
prototype是函式的屬性。__proto__是物件的屬性,指向它的prototype。Object.prototype是所有物件的最終原型。
3. class 關鍵字
ES6 之後,JavaScript 引入了 class 語法,使物件導向的寫法更直覺。
定義類別 (Class)
class Car { |
等同於 ES5 的寫法:
function Car(brand) { |
優勢:
class提供更簡潔的語法。- 更貼近傳統物件導向語言的語法風格。
constructor方法負責初始化物件。- 方法定義在
prototype上,並不會重複創建。
4. extends 繼承
在 ES6 之前,我們使用 Object.create() 或手動設定 prototype 來實現繼承。
傳統的原型繼承
function Animal(name) { |
使用 class 的繼承
class Animal { |
關鍵點:
extends用於建立類別的繼承。super(name)呼叫父類別的constructor,確保this正確初始化。- 子類別可以新增自己的方法。
5. 物件導向開發的最佳實踐
- 使用
class提供更清晰的結構。 - 使用
extends來建立繼承關係,並呼叫super()確保正確初始化。 - 方法定義於
prototype來減少記憶體浪費。 - 理解
__proto__和prototype之間的關係,以便更好地管理原型鏈。 - 避免過度使用繼承,適時使用組合 (Composition) 來降低耦合度。
6. 總結
| 特性 | 傳統原型 (Prototype) | ES6 class |
|---|---|---|
| 建立物件 | new Function() |
new Class() |
| 方法定義 | Function.prototype.method = function() {} |
直接定義於 class |
| 繼承 | Object.create() + call() |
extends + super() |
this 綁定 |
需要 call() 或 bind() |
super() 自動綁定 |
JavaScript 的物件導向概念提供了靈活的方式來組織程式碼,掌握 prototype、class、extends 和 super(),可以幫助開發者寫出更具可讀性與可維護性的程式碼。