使用 new 關鍵字來創建物件的完整解析
更新日期: 2024 年 11 月 4 日
在 JavaScript 中,new
關鍵字是用於創建和初始化物件的核心工具之一。
透過 new
,我們可以將一個函式(通常稱作「建構函式」)轉化為一個物件模板,用於生成具有特定屬性或行為的物件。
以下,我們會深入解析 new
關鍵字的運作機制,並說明建構函式如何創建出新的物件。
本文將以一個代碼範例作為例子來解釋 new
的詳細流程,幫助你更好地理解它的工作原理和應用方式。
代碼概述與範例
以下是一段使用 new
關鍵字的代碼示例。
我們會逐步分析這段代碼,以解釋它在每一個步驟中發生了什麼。
// heroCreator 建構函式,用於創建具有 name 和 power 屬性的英雄物件
function heroCreator(name, power) {
// 步驟 1: this 指向新物件 {}
// 步驟 1.5: {}.__proto__ 指向 heroCreator.prototype
this.name = name;
this.power = power;
// 步驟 2: 自動 return this (無需顯式 return)
}
// 使用 new 關鍵字創建新物件
const h1 = new heroCreator('kk', 100);
在這段代碼中,我們定義了一個名為 heroCreator
的建構函式。
這個函式接收兩個參數:name
和 power
。
當使用 new
關鍵字調用 heroCreator
函式時,JavaScript 會創建一個新物件,並自動設置該物件的 name
和 power
屬性。
接下來我們逐步分析這段代碼的運作原理。
new
關鍵字的工作原理
new
關鍵字執行的過程可以分為以下四個步驟,每一步都有特定的行為:
步驟 1:創建新物件並設置 this
指向新物件
當我們使用 new heroCreator('kk', 100);
調用建構函式時,new
會先創建一個空的物件 {}
,並將 this
關鍵字指向這個新物件。
這意味著在 heroCreator
函式內部,this
變量的值會自動指向新創建的物件。
這一過程確保了 heroCreator
函式能夠直接修改新物件的屬性。
在這個過程中,我們可以將 this
視為新物件的代表。
因此,當我們在建構函式中賦值時,例如 this.name = name;
,實際上是在為新物件添加屬性。
步驟 1.5:設置新物件的 __proto__
指向建構函式的 prototype
JavaScript 中的每個函式都自帶一個 prototype
屬性。
這是一個物件,包含了所有該建構函式的實例,可以共享的屬性和方法。
new
關鍵字創建新物件後,會自動設置新物件的 __proto__
屬性,讓它指向建構函式的 prototype
。
這樣一來,新物件就可以繼承 heroCreator.prototype
上的屬性或方法。
例如,如果我們在 heroCreator.prototype
上添加一個方法,所有使用 heroCreator
創建的物件都可以訪問該方法:
heroCreator.prototype.getDescription = function() {
return `${this.name} 擁有 ${this.power} 的力量`;
};
// 這樣 h1.getDescription() 就會返回 "kk 擁有 100 的力量"
這個步驟建立了 JavaScript 的原型鏈,使所有透過 new heroCreator()
創建的物件能共享 heroCreator.prototype
中定義的行為。
步驟 2:執行建構函式內部代碼
在完成指向新物件的設置後,JavaScript 開始執行建構函式內的代碼。
在這段代碼中,我們看到以下兩行代碼:
this.name = name;
this.power = power;
這些代碼的作用是將建構函式接收到的參數 name
和 power
存儲到新物件的 name
和 power
屬性上。例如,在 new heroCreator('kk', 100);
調用中,this.name
會被設置為 'kk'
,而 this.power
會被設置為 100
。此時,我們的新物件已經擁有了 name
和 power
這兩個屬性。
步驟 3:自動返回新物件
在 JavaScript 中,如果建構函式沒有顯式地 return
物件,則 new
關鍵字會自動返回新創建的物件(即 this
所指的物件)。
這也是為什麼在建構函式中不需要 return
語句。
如果我們嘗試手動 return
一個原始值(例如數字或字符串),該返回值會被忽略,JavaScript 還是會返回新物件。
例子解說:使用 new
創建新物件
現在我們來看代碼中的一行:
const h1 = new heroCreator('kk', 100);
這行代碼創建了一個名為 h1
的新物件,這個物件具有以下屬性:
h1.name
,其值為'kk'
h1.power
,其值為100
另外,h1
的 __proto__
指向 heroCreator.prototype
。
如果 heroCreator.prototype
上有任何屬性或方法,h1
都可以訪問到,例如 h1.getDescription()
,它會返回 "kk 擁有 100 的力量"
。
new
的優勢與應用情境
使用 new
關鍵字來創建物件,有以下幾個優勢:
- 物件創建自動化:
使用new
關鍵字時,JavaScript 會自動創建物件並設置原型鏈,避免了手動設置屬性和方法的繁瑣操作。 - 共享方法節省內存:
使用prototype
共享方法,可以減少每個實例重複的代碼。所有透過new
創建的物件都會共享相同的prototype
,這意味著節省了內存空間。 - 統一的構造模式:
使用建構函式可以建立一個標準化的模板,用於生成特定類型的物件。這對於大型應用程式來說尤為重要,因為可以確保所有物件的行為一致。
結論
透過 new
關鍵字和建構函式,我們可以輕鬆且一致地創建並初始化具有特定屬性和方法的物件。
這不僅使物件創建過程更加直觀,還能通過原型鏈的設置,實現方法共享和內存節省。
理解 new
的工作原理有助於更靈活地在 JavaScript 中創建和管理物件結構,並且能提升代碼的可讀性和維護性。