使用 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 的建構函式。

這個函式接收兩個參數:namepower

當使用 new 關鍵字調用 heroCreator 函式時,JavaScript 會創建一個新物件,並自動設置該物件的 namepower 屬性。

接下來我們逐步分析這段代碼的運作原理。

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;

這些代碼的作用是將建構函式接收到的參數 namepower 存儲到新物件的 namepower 屬性上。例如,在 new heroCreator('kk', 100); 調用中,this.name 會被設置為 'kk',而 this.power 會被設置為 100。此時,我們的新物件已經擁有了 namepower 這兩個屬性。

步驟 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 關鍵字來創建物件,有以下幾個優勢:

  1. 物件創建自動化
    使用 new 關鍵字時,JavaScript 會自動創建物件並設置原型鏈,避免了手動設置屬性和方法的繁瑣操作。
  2. 共享方法節省內存
    使用 prototype 共享方法,可以減少每個實例重複的代碼。所有透過 new 創建的物件都會共享相同的 prototype,這意味著節省了內存空間。
  3. 統一的構造模式
    使用建構函式可以建立一個標準化的模板,用於生成特定類型的物件。這對於大型應用程式來說尤為重要,因為可以確保所有物件的行為一致。

結論

透過 new 關鍵字和建構函式,我們可以輕鬆且一致地創建並初始化具有特定屬性和方法的物件。

這不僅使物件創建過程更加直觀,還能通過原型鏈的設置,實現方法共享和內存節省。

理解 new 的工作原理有助於更靈活地在 JavaScript 中創建和管理物件結構,並且能提升代碼的可讀性和維護性。

Similar Posts