Skip to content

2026-05-24

/ 11 分鐘閱讀

/ JavaScript Hard Parts v3

Public Instance Fields 的執行流程

完整執行流程逐步拆解

以下程式碼展示了 public instance field 如何在物件建立時自動附加:

javascript
class UserCreator {
    loggedIn = false;
    constructor(name, score) {
        this.name = name;
        this.score = score;
    }
    increment() {
        this.score++;
    }
    login() {
        this.loggedIn = true;
    }
}

const user1 = new UserCreator('Ari', 3);
user1.login();

執行 new UserCreator("Ari", 3) 時,JavaScript 依序完成以下步驟:

第一步:參數指派

進入執行環境後,先處理參數與引數的配對,在本地記憶體中建立 name = "Ari"score = 3

第二步:new 自動建立空物件

new 關鍵字建立一個空物件,並將其指派給隱含參數 this

第三步:設定 [[prototype]] 連結

這個空物件的隱藏 [[prototype]] 連結自動指向 UserCreator.prototype,那裡存放著 incrementlogin 方法。

第四步:套用 Public Instance Fields

new 在執行任何 constructor 內的程式碼之前,先去讀取 class 定義時儲存在函式物件組合隱藏屬性 fields 中的內容,並自動將它們加入 this 物件。在這個例子中,loggedIn = false 被加進來,此時物件上已有 loggedIn: false

第五步:執行 constructor 主體

接著才執行我們手寫的那兩行:this.name = "Ari"this.score = 3,將屬性加入物件。

第六步:自動回傳物件

new 將完成後的物件回傳,存入 user1。此時 user1 的完整狀態為:

user1: {
  loggedIn: false,   ← 由 fields 自動加入
  name: "Ari",       ← constructor 手動加入
  score: 3           ← constructor 手動加入
  [[prototype]] → UserCreator.prototype(存有 increment、login)
}

呼叫 user1.login() 的查找流程

執行 user1.login() 時:

  1. user1 自身上查找 login,只找到 loggedInnamescore,找不到。
  2. 沿 [[prototype]] 前往 UserCreator.prototype,找到 login
  3. 建立新執行環境,this 自動設為 user1
  4. 執行 this.loggedIn = true,即 user1.loggedIn = true

Public Instance Field 的本質

Public instance field 存放於函式物件組合的一個隱藏屬性 fields 中。每次以 new 呼叫建構函式時,JavaScript 都會在執行 constructor 主體之前,先從 fields 讀取這些預設值並附加到新物件上。每個實例都擁有自己獨立的一份,適合用來設定預設值。

複習

從 class 建立物件時,new 關鍵字的第一個自動步驟是什麼?

new 關鍵字建立一個全新的空物件,並將其指派給執行環境中的 this

使用 new 關鍵字搭配 class 建構函式時,JavaScript 會自動將隱藏的 __proto__ 連結指向哪裡?

__proto__ 連結會被設定為指向函式物件組合上的 prototype 物件,也就是建構函式的 prototype 屬性,即範例中的 userCreator.prototype

什麼是 JavaScript class 中的 public instance field?它最初儲存在哪裡?

Public instance field 是一個在每個由 class 建立的新物件上都存在的屬性,每個物件各自擁有一份副本。它最初儲存在透過 class 關鍵字建立的函式物件組合的隱藏屬性 fields 中。

JavaScript 在什麼時候將 public instance fields 自動加入新建立的物件?

JavaScript 在執行 constructor 主體的程式碼之前就會自動加入。new 關鍵字會讀取儲存在 fields 隱藏屬性中的內容,並在 constructor 執行前先將它們指派到自動建立的物件上。

當嘗試存取物件上不存在的方法時,會發生什麼事?

JavaScript 首先在物件自身上尋找該方法。若找不到,便透過隱藏的 __proto__ 連結沿原型鏈查找,前往建構函式的 prototype 物件,那裡存放著 incrementlogin 等方法。

小測驗

從 class 建立實例時,哪個關鍵字負責自動建立物件並處理原型連結? new
在 class 中定義的 `increment` 和 `login` 等方法儲存在哪裡? 儲存在 prototype 物件上
使用 `new` 關鍵字時,自動建立的空物件被指派給哪個標籤(label)? this
物件上隱藏的 `__proto__` 連結的作用是什麼? 連結到 prototype 物件,以便沿原型鏈查找屬性
在屬性查找過程中,若某個屬性在物件自身上找不到,會發生什麼事? JavaScript 透過 `__proto__` 連結沿原型鏈繼續查找

此文章是 FrontendMasters 上的 The Hard Parts of JavaScript 課程筆記

最後更新時間:

Buy Me A Coffee

系列章節 第 48 篇 / 共 48 篇

0 %
MIT Licensed | Copyright © 2025-present Wen-Hsiu's Blog
Photo by Federica Galli on Unsplash