Skip to content

Lesson 1.1.4 — Creation Phase vs Execution Phase ​

Bài 1.1.4 — Creation vs Execution Phase
Bindings, Initialization & Execution Flow • 30 phút
0:00 / 0:00

0. Metadata (Thông tin bài học) ​

TrườngGiá trị
Stage1 — JavaScript Execution Model
Module1.1 — Execution Context
Lesson1.1.4 — Creation Phase vs Execution Phase
CompetencyC02 — JavaScript Runtime
DepthL2–L3 (Explain → Use)
PrerequisitesLesson 1.1.1–1.1.3 — Execution Context, Global FEC, Function FEC
Thời gian ước tính35–45 phút

1. Why This Exists (Vì sao cần học) ​

Bạn đã biết Execution Context là container nơi code chạy. Bạn cũng biết mỗi lần gọi hàm tạo ra một Function Execution Context mới.

Nhưng câu hỏi này sẽ làm bạn dừng lại:

js
console.log(greet);

function greet() {
  return "hello";
}

Nếu bạn nghĩ engine đọc code từ trên xuống, dòng đầu tiên chạy trước, thì greet ở dòng 1 phải là undefined hoặc lỗi. Nhưng khi chạy:

text
[Function: greet]

greet đã tồn tại trước khi dòng định nghĩa function greet() được thực thi.

Tại sao?

Vì mỗi Execution Context không chạy code ngay lập tức. Engine chuẩn bị trước, rồi mới chạy sau.

Nếu không hiểu hai phase này, bạn sẽ:

  • Không hiểu tại sao function có thể gọi trước khi định nghĩa
  • Không hiểu tại sao var x tồn tại nhưng lại là undefined trước dòng khai báo
  • Không thể học Hoisting (Module 1.3) vì hoisting chính là hệ quả của Creation Phase
  • Không thể debug lỗi ReferenceError vs undefined một cách có hệ thống

2. Prerequisites (Yêu cầu đầu vào) ​

Bạn cần đã học:

  • Lesson 1.1.1 — Execution Context là gì?
  • Lesson 1.1.2 — Global Execution Context
  • Lesson 1.1.3 — Function Execution Context
  • Biết var, let, const, function declaration

3. Learning Objectives (Mục tiêu học tập) ​

Sau bài này, bạn có thể:

  1. Giải thích tại sao mỗi Execution Context có hai phase: Creation và Execution
  2. Phân biệt những gì xảy ra trong Creation Phase (setup) và Execution Phase (run)
  3. Dự đoán giá trị của biến/hàm tại một dòng code cụ thể dựa trên phase hiện tại
  4. Trace luồng từ Creation Phase sang Execution Phase trong một đoạn code đơn giản

4. Mental Model (Mô hình tư duy) ​

Mỗi Execution Context = Chuẩn bị trước, chạy sau

Khi engine tạo ra một Execution Context (Global hoặc Function), nó không chạy code ngay. Nó làm hai việc theo thứ tự:

text
1. Creation Phase (Chuẩn bị)
   → Tạo không gian cho biến và hàm
   → Thiết lập liên kết ra bên ngoài
   → Thiết lập `this`

2. Execution Phase (Thực thi)
   → Chạy từng dòng code
   → Gán giá trị cho biến
   → Thực thi expression

Đây là mental model pedagogical. Formal specification dùng thuật ngữ khác chi tiết hơn, nhưng predictive value là tương đương.

text
FUNCTION CALL
     ↓
┌──────────────────────────────┐
│  Creation Phase              │
│  • Tạo chỗ cho biến/hàm      │
│  • Thiết lập outer link      │
│  • Thiết lập this            │
└──────────────┬───────────────┘
               ↓
┌──────────────────────────────┐
│  Execution Phase             │
│  • Chạy code từng dòng       │
│  • Gán giá trị thực          │
│  • Tính toán expression      │
└──────────────┬───────────────┘
               ↓
            return

Đây là simplification

Ở L2–L3, chúng ta hình dung Creation Phase là "chuẩn bị chỗ" và Execution Phase là "chạy code". Điều này đủ để dự đoán hoisting behavior. Chi tiết chính xác về Environment Record và Lexical Environment sẽ được dạy ở Module 1.2. this binding sẽ được dạy ở Stage 2.

Tư duy phòng khách sạn

Hãy tưởng tượng bạn thuê một phòng (tạo Execution Context):

  • Creation Phase: Nhân viên dọn phòng, đặt sẵn tủ đựng đồ, treo sẵn móc áo — nhưng chưa có đồ của bạn. Họ chuẩn bị chỗ cho đồ.
  • Execution Phase: Bạn vào phòng, đặt vali lên giường, treo áo lên móc — bạn đang dùng chỗ đã chuẩn bị.

Nếu bạn mở tủ trong lúc nhân viên đang dọn (giữa Creation và Execution), bạn thấy tủ trống hoặc chưa sẵn sàng — đó chính là lý do var tồn tại nhưng là undefined trước khi code gán giá trị.

5. Core Concepts (Các khái niệm cốt lõi) ​

Essential (Bắt buộc) ​

  • Creation Phase: Giai đoạn engine chuẩn bị môi trường — tạo chỗ cho bindings, thiết lập outer reference, thiết lập this
  • Execution Phase: Giai đoạn engine chạy code thực sự — gán giá trị, thực thi statement, tính expression
  • Binding: Liên kết giữa tên biến/hàm và vị trí lưu trữ trong context
  • Hoisting preview: Hàm declaration được "nhớ" trong Creation Phase, biến var được tạo nhưng chưa có giá trị

Supporting (Hỗ trợ) ​

  • var trong Creation Phase: tạo binding, khởi tạo undefined
  • function declaration trong Creation Phase: tạo binding, khởi tạo function object
  • let/const trong Creation Phase: tạo binding nhưng không khởi tạo (TDZ preview — Module 1.3)

Awareness (Biết tồn tại) ​

  • this được thiết lập trong Creation Phase, nhưng cơ chế chi tiết thuộc Stage 2
  • Lexical Environment và Environment Record là implementation detail của Creation Phase (Module 1.2)

Out of Scope (Không học trong bài này) ​

  • Hoisting mechanism đầy đủ (Module 1.3)
  • Temporal Dead Zone chi tiết (Module 1.3)
  • this binding rules (Stage 2)
  • Lexical Environment internals (Module 1.2)
  • JIT compilation / hidden classes (Stage 11)

6. Worked Example (Ví dụ phân tích từng bước) ​

Xem đoạn code sau:

js
console.log(a);
console.log(b);

var a = 10;
function b() {
  return 20;
}

Bước 1 — Quan sát Có 4 dòng code. Nếu engine chạy từ trên xuống theo nghĩa đen, dòng 1 và 2 phải lỗi vì a và b chưa được định nghĩa.

Bước 2 — Phân loại

  • Dòng 1–2: Execution Phase behavior (đọc biến)
  • Dòng 3: var a (declaration) + = 10 (initialization)
  • Dòng 4: function b (declaration)

Bước 3 — Lý luận từng bước

text
1. Global Execution Context được tạo

2. CREATION PHASE bắt đầu
   → Engine quét toàn bộ code trong context
   → Thấy "var a" → tạo binding cho a, gán undefined
   → Thấy "function b" → tạo binding cho b, gán function object
   → Thấy console.log (không phải declaration, bỏ qua)
   → Thấy "= 10" là assignment → xử lý ở Execution Phase (không phải declaration, bỏ qua)

3. EXECUTION PHASE bắt đầu
   → Dòng 1: console.log(a)
     → a đã có binding từ Creation Phase
     → Giá trị hiện tại: undefined
     → Output: undefined

   → Dòng 2: console.log(b)
     → b đã có binding từ Creation Phase
     → Giá trị hiện tại: function object
     → Output: [Function: b]

   → Dòng 3: var a = 10
     → Declaration đã xử lý ở Creation Phase
     → Chỉ thực thi phần "= 10"
     → a = 10

   → Dòng 4: function b() {...}
     → Declaration đã xử lý ở Creation Phase
     → Không còn việc gì để làm ở dòng này

Bước 4 — Kết luậnvar và function được "chuẩn bị chỗ" trong Creation Phase, nên khi Execution Phase chạy đến, chúng đã tồn tại. var được khởi tạo undefined, còn function được khởi tạo sẵn function object.

7. Prediction Exercise (Bài tập dự đoán) ​

Đừng chạy code. Đọc và trả lời:

js
function test() {
  console.log(x);
  console.log(y);

  var x = 5;
  function y() {
    return 10;
  }
}

test();

Câu hỏi:

  1. console.log(x) in ra gì? Nó lấy giá trị từ đâu?
  2. console.log(y) in ra gì? Tại sao không phải undefined?
  3. Nếu đổi var x = 5 thành let x = 5, console.log(x) sẽ ra gì? (Hint: let không khởi tạo trong Creation Phase)
[Đáp án & Giải thích]
  • Bạn nghĩ

    1. undefined — vì var x được tạo trong Creation Phase với giá trị undefined, nhưng = 5 chưa chạy.
    2. [Function: y] — vì function declaration được khởi tạo hoàn chỉnh trong Creation Phase.
    3. ReferenceError — vì let tạo binding trong Creation Phase nhưng không khởi tạo, để trong Temporal Dead Zone cho đến dòng khai báo.
  • Giải thích

    • Khi test() được gọi, tạo FEC cho test.
    • Creation Phase: engine quét body của test, thấy var x → tạo binding với undefined; thấy function y → tạo binding với function object.
    • Execution Phase: chạy từng dòng.
      • console.log(x) → x đã tồn tại, giá trị undefined.
      • console.log(y) → y đã tồn tại, giá trị là function object.
      • var x = 5 → gán x = 5.
    • Nếu dùng let x = 5: Creation Phase tạo binding cho x nhưng không gán gì cả. Khi console.log(x) chạy, engine thấy binding tồn tại nhưng chưa được khởi tạo → ReferenceError: Cannot access 'x' before initialization. Đây là TDZ, sẽ học chi tiết ở Module 1.3.

8. Implementation Lab (Bài lab thực hành) ​

Lab 1 — Trace Creation vs Execution (Guided) ​

Cho đoạn code sau. Hãy viết ra những gì xảy ra trong Creation Phase và Execution Phase của Function Execution Context setup():

js
function setup() {
  console.log(status);
  console.log(init);

  var status = "ready";
  function init() {
    return "done";
  }
}

setup();

Gợi ý

  • Creation Phase: engine chỉ quét declaration (var, function), không chạy console.log
  • Execution Phase: engine chạy từng dòng từ trên xuống
[Đáp án tham khảo]
  • Creation Phase (trong FEC của setup)

    • Quét body của setup
    • Thấy var status → tạo binding status = undefined
    • Thấy function init → tạo binding init = function object
    • Bỏ qua console.log và = "ready" (không phải declaration)
  • Execution Phase

    • Dòng 1: console.log(status) → undefined
    • Dòng 2: console.log(init) → [Function: init]
    • Dòng 3: var status = "ready" → gán status = "ready"
    • Dòng 4: function init() {...} → declaration đã xử lý, không làm gì thêm

Lab 2 — Dự đoán Phase (Independent) ​

Cho đoạn code sau. Hãy xác định: dòng nào xảy ra trong Creation Phase, dòng nào xảy ra trong Execution Phase?

js
function app() {
  const title = "JEM";
  console.log(title);
  helper();

  function helper() {
    console.log("help");
  }
}

app();
[Đáp án tham khảo]
  • Creation Phase của app()

    • Quét body của app
    • Thấy const title → tạo binding (không khởi tạo — TDZ)
    • Thấy function helper → tạo binding với function object
    • Bỏ qua console.log, helper() call, = "JEM"
  • Execution Phase của app()

    • const title = "JEM" → khởi tạo title
    • console.log(title) → in "JEM"
    • helper() → gọi hàm → tạo FEC mới cho helper
  • Creation Phase của helper()

    • Không có declaration nào trong body của helper
    • Không tạo binding nào
  • Execution Phase của helper()

    • console.log("help") → in "help"

9. Edge Cases (Các trường hợp ngoại lệ) ​

Case 1 — Function expression không được "hoist" đầy đủ ​

js
console.log(a);
console.log(b);

var a = function () {
  return 1;
};
function b() {
  return 2;
}
  • What fails? console.log(a) ra undefined, không phải function
  • Why? var a = function() {...} là function expression gán cho biến var. Trong Creation Phase, chỉ var a được xử lý → a = undefined. Phần = function() {...} là assignment, chạy trong Execution Phase. Ngược lại, function b() là function declaration → được khởi tạo hoàn chỉnh trong Creation Phase.
  • How to observe? console.log(a) → undefined, console.log(b) → [Function: b]
  • How to fix/decide? Nếu cần gọi hàm trước khi định nghĩa, dùng function declaration. Nếu cần conditional assignment, dùng function expression nhưng đừng gọi trước.

Case 2 — let/const tồn tại nhưng không dùng được trong Creation Phase ​

js
function demo() {
  console.log(x);
  let x = 10;
}

demo();
  • What fails? ReferenceError: Cannot access 'x' before initialization
  • Why? let x tạo binding trong Creation Phase, nhưng không khởi tạo. Binding nằm trong Temporal Dead Zone (TDZ) cho đến dòng khai báo. Khác với var (khởi tạo undefined), let không cho phép truy cập trước khi đến dòng khai báo.
  • How to observe? Chạy code và thấy ReferenceError thay vì undefined
  • How to fix/decide? Khai báo biến trước khi dùng. Đây là lý do let/const an toàn hơn var — chúng ngăn bạn vô tình dùng biến chưa được khởi tạo.

10. Debug Lab (Bài lab gỡ lỗi) ​

Symptom (Triệu chứng): Developer báo cáo: "Tôi định nghĩa hàm calculate bằng var, nhưng khi gọi trước khai báo thì bị lỗi TypeError: calculate is not a function."

Reproduction (Tái hiện lỗi):

js
console.log(calculate(5));

var calculate = function (num) {
  return num * 2;
};

Evidence (Bằng chứng): TypeError: calculate is not a function thay vì ReferenceError.

Hypothesis (Giả thuyết): Developer nhầm lẫn giữa function declaration và function expression. var calculate = function() {...} là function expression gán cho biến var. Trong Creation Phase, chỉ var calculate được xử lý → calculate = undefined. Khi console.log(calculate(5)) chạy ở Execution Phase, calculate là undefined, không phải function → TypeError.

Verification (Xác minh): Đổi var calculate = function thành function calculate() — lỗi biến mất vì function declaration được khởi tạo hoàn chỉnh trong Creation Phase.

Root Cause (Nguyên nhân gốc rễ): Không phân biệt Creation Phase behavior giữa function declaration (khởi tạo sẵn function object) và function expression gán cho var (chỉ tạo binding undefined, assignment chạy sau ở Execution Phase).

Prevention (Phòng ngừa):

  • Nếu cần gọi hàm trước định nghĩa, dùng function calculate() {} (declaration)
  • Nếu dùng function expression, đảm bảo khai báo trước khi gọi
  • Không dùng var cho function expression nếu có thể dùng const — const sẽ throw ReferenceError rõ ràng hơn TypeError mơ hồ

11. Design Exercise (Bài tập thiết kế giải pháp) ​

Không áp dụng ở Depth L2–L3.

12. Production Scenario (Tình huống thực tế) ​

Context: Một codebase legacy có nhiều file JavaScript được nối qua thẻ <script>. File thứ hai dùng một hàm được định nghĩa ở file thứ nhất.

Constraint: File 1 định nghĩa hàm bằng var process = function(data) {...}. File 2 gọi process(items) ở dòng đầu tiên.

Symptom: Khi tải trang, đôi khi thấy TypeError: process is not a function, đôi khi lại chạy bình thường.

Decision cần đưa ra: Dùng kiến thức về Creation Phase và Execution Phase, giải thích tại sao lỗi này xảy ra ngẫu nhiên (race condition giữa thứ tự load file và thứ tự chạy code), và đề xuất fix.

Gợi ý

Vấn đề không nằm ở Creation Phase/Execution Phase trong một file, mà ở thứ tự load script. Nếu File 2 load và chạy trước File 1, process chưa tồn tại. Tuy nhiên, nếu developer nghĩ var process = function sẽ "hoist" giống function process(), họ đã hiểu sai Creation Phase behavior. Fix: đổi thành function process(data) {...} (hoist hoàn toàn) hoặc đảm bảo thứ tự load + dùng event listener đợi DOM ready.

13. AI-Assisted Exercise (Bài tập với AI) ​

Level A — Ask

  1. Tự trả lời trước: Viết ra giấy: "Tại sao function foo() {} có thể gọi trước khi định nghĩa, nhưng var foo = function() {} thì không?"
  2. Hỏi AI: Dùng prompt: "In JavaScript, why can I call a function before its declaration using 'function foo() {}', but not with 'var foo = function() {}'? Explain using execution context phases."
  3. So sánh: AI có nhắc đến Creation Phase và Execution Phase không? AI có phân biệt rõ function declaration vs function expression không? AI có dùng từ "hoisted" một cách mơ hồ cho cả hai trường hợp không?
  4. Verify: Mở MDN "Function", tìm phần "Function declaration hoisting" và "Function expression". Kiểm chứng xem AI có bỏ sót điểm nào.

Gợi ý

Để ý xem AI có nói "both are hoisted" không. Câu trả lời đúng cần phân biệt: function declaration được khởi tạo hoàn chỉnh trong Creation Phase; function expression gán cho var chỉ có biến được tạo (undefined), còn assignment chạy ở Execution Phase. Nếu AI gộp cả hai thành "hoisted", bạn đã tìm ra điểm mù.

Đáp án tham khảo
  • Bạn nghĩfunction foo() {} là function declaration. Trong Creation Phase, engine thấy declaration này và tạo binding hoàn chỉnh — gán sẵn function object. Nên khi Execution Phase chạy, foo đã là function. Còn var foo = function() {} là function expression gán cho biến var. Trong Creation Phase, chỉ var foo được xử lý → foo = undefined. Phần = function() {} là assignment, chạy trong Execution Phase. Nếu gọi trước assignment, foo vẫn là undefined.

  • AI trả lời

    • "Both function declarations and var declarations are hoisted, but they behave differently."
    • "A function declaration like function foo() {} is hoisted with its full definition, so you can call it before the line where it appears."
    • "A function expression assigned to a var like var foo = function() {} is hoisted only as a variable declaration. The assignment happens at runtime, so calling it before the assignment results in undefined."
    • "This is because of how JavaScript execution contexts work — declarations are processed in the creation phase, while assignments happen in the execution phase."
  • So sánh

    • AI đúng về điểm chính: declaration hoàn chỉnh vs chỉ variable hoisted.
    • AI có nhắc đến Creation Phase và Execution Phase — tốt.
    • AI dùng từ "hoisted" cho cả hai trường hợp. Điều này kỹ thuật đúng nhưng dễ gây hiểu nhầm: learner có thể nghĩ "hoisted" nghĩa là giống nhau. Sự khác biệt nằm ở mức độ khởi tạo trong Creation Phase.
    • AI không nhắc đến let/const function expression — một điểm mù vì const foo = function() {} sẽ throw ReferenceError thay vì TypeError.
  • Điểm AI nói sai hoặc quá mơ hồ

    • AI nói "both are hoisted" mà không làm rõ sự khác biệt về giá trị khởi tạo. Function declaration được gán function object ngay trong Creation Phase; var chỉ được gán undefined. Đây là điểm then chốt để dự đoán behavior.
    • AI không nhắc đến const foo = function() {}. Nếu dùng const thay vì var, việc gọi trước assignment sẽ throw ReferenceError (do TDZ) thay vì TypeError — một điểm mù quan trọng khi chọn kiểu khai báo.
  • Kết luận Nếu bạn phát hiện AI dùng "hoisted" như một từ chung chung mà không phân biệt mức độ khởi tạo, bạn đã hiểu sâu hơn AI về Creation Phase. Điều này sẽ cực kỳ quan trọng khi bạn học Module 1.3 (Hoisting & TDZ) và Module 1.4 (Closure), nơi sự khác biệt giữa "tạo binding" và "khởi tạo giá trị" quyết định behavior.

14. Teach Back (Dạy lại) ​

Yêu cầu: Giả sử một junior developer hỏi: "Tôi đọc trên mạng nói JavaScript 'hoist' biến và hàm. Tại sao console.log(foo) ra undefined nhưng console.log(bar) lại ra function khi cả hai đều được định nghĩa sau dòng console.log?"

js
console.log(foo);
console.log(bar);

var foo = 10;
function bar() {
  return 20;
}

Hãy giải thích trong 2 phút, dùng khái niệm Creation Phase và Execution Phase.

Mô phỏng
  • Bạn nói Khi file này chạy, engine tạo Global Execution Context. Nhưng nó không chạy code ngay — nó có hai giai đoạn. Creation Phase là giai đoạn chuẩn bị: engine quét toàn bộ code, thấy var foo thì tạo chỗ cho foo và gán undefined; thấy function bar thì tạo chỗ cho bar và gán luôn function object. Rồi đến Execution Phase: engine chạy từng dòng từ trên xuống. Dòng đầu console.log(foo) — lúc này foo đã có chỗ nhưng giá trị là undefined vì phần = 10 chưa chạy. Dòng hai console.log(bar) — bar đã có sẵn function object từ Creation Phase nên in ra function. Vậy nên cả hai đều "hoist" về mặt declaration, nhưng mức độ chuẩn bị khác nhau: var chỉ chuẩn bị chỗ trống, còn function chuẩn bị cả nội dung.

💡 Hình dung như setup một sự kiện: Creation Phase là lúc bạn đặt bàn ghế sẵn — var là đặt bàn trống, function là đặt bàn và xếp sẵn đồ ăn. Execution Phase là lúc khách đến. Nếu khách nhìn bàn var trước khi bạn dọn đồ lên, họ thấy trống (undefined). Nhưng bàn function đã có sẵn món ăn từ lúc setup.

Gợi ý đánh giá bản thân

  • Đồng nghiệp có hiểu tại sao cả hai đều "tồn tại" nhưng giá trị khác nhau không?
  • Bạn có dự đoán được câu hỏi tiếp: "Vậy let thì sao?" không? (Trả lời: let tạo bàn nhưng dán băng keo "chưa được mở" — TDZ.)
  • Bạn có thể trace được nếu họ đổi var foo = 10 thành foo = 10 (không khai báo) không? (Trả lời: Không có declaration → không tạo binding trong Creation Phase → ReferenceError ở strict mode, hoặc tạo global property ở non-strict.)

15. Assessment (Đánh giá) ​

Objective (Mục tiêu)Hình thức đánh giáNội dung
Giải thích hai phaseExplain (Giải thích)Liệt kê 3 thành phần chính của Creation Phase và 3 thành phần chính của Execution Phase
Creation vs ExecutionClassification (Phân loại)Cho đoạn code 10 dòng, phân loại dòng nào xảy ra ở Creation Phase, dòng nào ở Execution Phase
Dự đoán giá trị biến/hàmPrediction (Dự đoán)Cho 4 đoạn code có var/function/let, đoán output tại dòng trước khai báo
Trace luồng Creation → ExecutionTrace (Truy vết)Cho code có 1–2 hàm, viết thứ tự xảy ra trong mỗi phase

16. Exit Criteria (Tiêu chí qua bài) ​

  • [ ] Có thể giải thích tại sao Execution Context có hai phase (chuẩn bị trước, chạy sau)
  • [ ] Có thể liệt kê ít nhất 2 việc xảy ra trong Creation Phase (tạo binding, thiết lập outer reference)
  • [ ] Có thể dự đoán đúng giá trị của var trước dòng khai báo (undefined) trong 2/2 scenario
  • [ ] Có thể dự đoán đúng giá trị của function declaration trước dòng định nghĩa (function object) trong 2/2 scenario
  • [ ] Có thể phân biệt function declaration (khởi tạo hoàn chỉnh trong Creation Phase) và function expression gán cho var (chỉ tạo binding undefined)
  • [ ] Có thể trace timeline Creation → Execution cho một hàm có var và function declaration

17. Spiral Connection (Liên kết xoắn ốc) ​

Previous (Trước): Lesson 1.1.1–1.1.3 — Bạn đã biết Execution Context là container, Global FEC luôn tồn tại, Function FEC được tạo mỗi khi gọi hàm và bị hủy khi return.

Current (Hiện tại): Bạn hiểu mỗi Execution Context có hai phase: Creation Phase (chuẩn bị bindings) và Execution Phase (chạy code). Bạn biết var và function declaration được xử lý trong Creation Phase, nhưng với mức độ khởi tạo khác nhau.

Next (Tiếp theo):

  • 1.2.x — Scope & Lexical Environment (cơ chế engine tìm biến qua outer reference đã thiết lập trong Creation Phase)
  • 1.3.x — Hoisting & Temporal Dead Zone (chi tiết hóa behavior của var, let, const, class trong Creation Phase)
  • 1.4.x — Closure (khi inner function giữ lại outer environment sau khi outer context đã kết thúc — ngoại lệ của "context bị hủy")
  • S2 — this binding (thiết lập this trong Creation Phase, chi tiết hóa ở Stage 2)
  • S11 — Memory & GC (context không bị hủy hoàn toàn nếu có reference giữ lại — nhưng đây là Stage 11, không học sớm)
📴 Offline Mode — Content served from cache