Skip to content

Lesson 1.3.4 — Temporal Dead Zone (TDZ — Vùng chết tạm thời) ​

Bài 1.3.4 — Temporal Dead Zone
Binding Lifecycle, TDZ & ReferenceError • 28 phút
0:00 / 0:00

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

FieldValue
Stage1 — JavaScript Execution Model
Module1.3 — Hoisting & Temporal Dead Zone
Lesson1.3.4 — Temporal Dead Zone
CompetencyC01.2 — Variables & Bindings
DepthL3–L4 (Use → Debug)
PrerequisitesLesson 1.3.1 (Declaration vs Initialization), Lesson 1.3.2 (var), Lesson 1.3.3 (let/const)
Cognitive LoadHigh

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

Bạn đã học rằng let và const được declare trong Creation Phase nhưng không initialize cho đến dòng khai báo. Nhưng câu hỏi quan trọng hơn là:

Nếu binding đã tồn tại trong Environment Record, tại sao engine không cho phép truy cập nó? Tại sao không trả về undefined như var?

Câu trả lời nằm ở Temporal Dead Zone — một khái niệm mà nhiều developer biết tên nhưng không hiểu mechanism. Họ nghĩ TDZ là "khoảng thời gian trước dòng khai báo", nhưng không hiểu tại sao nó tồn tại và tại sao nó quan trọng.

Nếu không hiểu TDZ, bạn sẽ không bao giờ giải thích được tại sao đoạn code này throw error:

js
let x = x; // ReferenceError: Cannot access 'x' before initialization

Hoặc tại sao typeof — vốn an toàn với biến chưa tồn tại — lại fail trong TDZ:

js
typeof undeclaredVar; // "undefined"
typeof tdzVar; // ReferenceError!
let tdzVar = 1;

Bài này xây dựng mental model chính xác về TDZ như trạng thái của binding, không phải khoảng thời gian.

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

Trước khi học bài này, bạn cần:

  • Phân biệt được Declaration, Initialization, Assignment (Lesson 1.3.1).
  • Hiểu var được declare + initialize (undefined) trong Creation Phase (Lesson 1.3.2).
  • Hiểu let/const được declare trong Creation Phase nhưng không initialize (Lesson 1.3.3).
  • Biết typeof trả về "undefined" cho biến chưa tồn tại (Stage 0).

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 Temporal Dead Zone là trạng thái của binding (uninitialized), không phải khoảng thời gian.
  2. Dự đoán khi nào code throw ReferenceError do TDZ thay vì do biến không tồn tại.
  3. Trace TDZ qua Creation Phase và Execution Phase cho let, const, và class.
  4. Debug bug TDZ trong code thực tế — đặc biệt khi refactor var → let hoặc dùng typeof.

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

Mental Model: TDZ là Trạng thái Uninitialized

┌─────────────────────────────────────────┐
│  Lexical Scope (Block / Function)       │
│                                         │
│  {                                      │
│    ←── TDZ bắt đầu: binding 'x'         │
│         được declare nhưng chưa         │
│         initialize                      │
│                                         │
│    console.log(x);  // ReferenceError   │
│                                         │
│    let x = 10;  ←── TDZ kết thúc:       │
│         binding được initialize         │
│                                         │
│    console.log(x);  // 10               │
│  }                                      │
└─────────────────────────────────────────┘

TDZ không phải là "thời gian chờ". Nó là trạng thái của binding trong Environment Record:

  • Trước TDZ: Binding chưa được declare → truy cập → ReferenceError: x is not defined
  • Trong TDZ: Binding đã được declare nhưng chưa initialize → truy cập → ReferenceError: Cannot access 'x' before initialization
  • Sau TDZ: Binding đã được initialize → truy cập → giá trị hợp lệ

Sai lầm phổ biến

"TDZ là khoảng thời gian từ đầu scope đến dòng khai báo."

Sai. TDZ không phải "thời gian" — nó là trạng thái uninitialized của binding. Điều quan trọng không phải "bao lâu" mà là binding đã tồn tại nhưng chưa sẵn sàng để dùng.

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

Essential (Bắt buộc) ​

ConceptĐịnh nghĩa
Temporal Dead Zone (TDZ)Trạng thái của binding khi nó đã được declare trong Environment Record nhưng chưa được initialize.
TDZ Error MessageReferenceError: Cannot access 'x' before initialization — khác với ReferenceError: x is not defined.
TDZ StartNgay đầu lexical scope chứa binding (sau dòng mở block {).
TDZ EndTại dòng khai báo let/const/class, khi binding được initialize.
typeof trong TDZtypeof throw ReferenceError nếu binding đang trong TDZ — khác với biến hoàn toàn không tồn tại.

Supporting (Hỗ trợ) ​

  • TDZ với class: class declaration cũng có TDZ tương tự let/const.
  • TDZ với default parameters: TDZ có thể xảy ra giữa các parameters của function.

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

  • TDZ với const trong for-of loop.
  • TDZ không áp dụng cho var vì var được initialize ngay trong Creation Phase.

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

  • Chi tiết spec algorithm của InitializeBinding và GetBindingValue.
  • TDZ trong destructuring phức tạp (sẽ đề cập ở mức awareness nếu xuất hiện trong example).

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

Trace đoạn code sau:

js
function check() {
  console.log(typeof value);
  let value = 42;
  console.log(value);
}
check();

Step 1 — Creation Phase (Function Execution Context của check)

  • Engine quét function body, thấy let value.
  • Declaration: Tạo binding value trong Block Environment Record của check.
  • Initialization: Không xảy ra. Binding ở trạng thái uninitialized → bắt đầu TDZ.

Trạng thái Environment Record:

text
value: <uninitialized>  (TDZ active)

Step 2 — Execution Phase

  • Dòng 2: console.log(typeof value) — engine cố gắng đọc binding đang trong TDZ.
  • Kết quả: ReferenceError: Cannot access 'value' before initialization.
  • Lưu ý: Đây không phải "undefined". typeof thường an toàn, nhưng không an toàn với TDZ.

Bây giờ so sánh với biến hoàn toàn không tồn tại:

js
console.log(typeof ghost); // "undefined"

Step 1 — Resolution

  • Engine tìm ghost trong tất cả Environment Records từ inner đến outer.
  • Không tìm thấy binding nào.
  • Kết quả: typeof trả về "undefined" — đây là behavior đặc biệt của typeof.

Code Review Lens

Khi debug ReferenceError, đọc kỹ message:

  • "x is not defined" → binding không tồn tại trong bất kỳ scope nào.
  • "Cannot access 'x' before initialization" → binding đã tồn tại nhưng đang trong TDZ.

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

Prediction 1

Đừng chạy code. Dự đoán output hoặc error, và phân biệt loại lỗi.

js
{
  console.log(a);
  let a = 10;
}
[Đáp án & Giải thích]
  • Bạn nghĩ

    • ReferenceError: Cannot access 'a' before initialization.
    • Binding a đã được declare trong Creation Phase nhưng chưa initialize.
  • Giải thích

    • TDZ bắt đầu từ đầu block {.
    • console.log(a) chạy trong TDZ → throw error.
    • Khác với var — nếu dùng var, output sẽ là undefined.

Prediction 2

Đừng chạy code. Dự đoán output hoặc error.

js
let x = x;
[Đáp án & Giải thích]
  • Bạn nghĩ

    • ReferenceError: Cannot access 'x' before initialization.
  • Giải thích

    • Dòng let x = x thực hiện theo thứ tự:
      1. Đánh giá right-hand side: x → binding đang trong TDZ → throw error.
      2. Assignment chưa kịp xảy ra.
    • Điều này chứng minh TDZ là trạng thái của binding, không phải "thời gian trước dòng khai báo". Ngay cả trong chính dòng khai báo, binding cũng chưa được initialize khi RHS được đánh giá.

Prediction 3 — Transfer Exercise

Đừng chạy code. Dự đoán output hoặc error.

js
function test(x = y, y = 1) {
  console.log(x, y);
}
test();
[Đáp án & Giải thích]
  • Bạn nghĩ

    • ReferenceError: Cannot access 'y' before initialization.
  • Giải thích

    • Parameters của function có scope riêng. y được declare trong parameter scope nhưng chưa initialize khi x = y được đánh giá.
    • y đang trong TDZ tại thời điểm x lấy giá trị default.
    • Đây là TDZ trong parameter list — ít gặp nhưng quan trọng.

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

Level 1 — Guided (Hướng dẫn) ​

Viết comment mô tả TDZ cho đoạn code sau:

js
function init() {
  // TDZ của 'config' bắt đầu từ đây
  console.log(config); // Error: Cannot access 'config' before initialization
  let config = { env: "prod" }; // TDZ kết thúc
  console.log(config); // { env: "prod" }
}

Level 2 — Partial Scaffold (Khung mẫu một phần) ​

Điền loại lỗi hoặc output cho từng dòng:

js
console.log(typeof ghost); // ___ (binding không tồn tại)
let phantom = 1;
console.log(typeof phantom); // ___ (binding đã initialize)
{
  console.log(typeof phantom); // ___ (truy cập từ inner scope)
  console.log(typeof specter); // ___ (binding trong cùng block, chưa declare)
  let specter = 2;
}
Đáp án
js
console.log(typeof ghost); // "undefined" (binding không tồn tại)
let phantom = 1;
console.log(typeof phantom); // "number" (binding đã initialize)
{
  console.log(typeof phantom); // "number" (truy cập từ inner scope, đã initialize)
  console.log(typeof specter); // ReferenceError: Cannot access 'specter' before initialization
  let specter = 2;
}

Level 3 — Independent (Tự thực hiện) ​

Viết một function ngắn (tối đa 8 dòng) trong đó:

  1. Một biến let được log ra trước dòng khai báo và throw TDZ error.
  2. Sử dụng typeof với biến đó (cũng throw TDZ error).
  3. Sử dụng typeof với một biến hoàn toàn không tồn tại (trả về "undefined").
  4. Giải thích sự khác biệt giữa 3 trường hợp bằng đúng 2 khái niệm: TDZ, binding existence.

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

Edge Case 1: TDZ với typeof ​

js
console.log(typeof ghost); // "undefined"
js
console.log(typeof value); // ReferenceError!
let value = 1;

typeof là toán tử duy nhất có thể truy cập biến không tồn tại mà không throw error. Nhưng nó không miễn nhiễm với TDZ. Điều này chứng minh TDZ binding đã tồn tại trong Environment Record — khác hoàn toàn với biến chưa được declare.

Edge Case 2: TDZ với class ​

js
const instance = new MyClass(); // ReferenceError!

class MyClass {
  constructor() {
    this.value = 42;
  }
}

class declaration cũng có TDZ tương tự let/const. Binding MyClass được declare trong Creation Phase nhưng chỉ được initialize (với class constructor) tại dòng khai báo.

Edge Case 3: TDZ trong Parameter Defaults ​

js
function test(a = b, b = 1) {
  return a + b;
}
test(); // ReferenceError: Cannot access 'b' before initialization

Parameters được xử lý từ trái sang phải. Khi a = b được đánh giá, b đã được declare trong parameter scope nhưng chưa initialize → TDZ.

TIP

Trong production, tránh dependencies giữa parameters. Nếu a phụ thuộc b, hãy tính toán trong function body thay vì default parameter.

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

Symptom (Triệu chứng): Developer refactor var → let trong một module lớn. Một số test pass, một số throw ReferenceError.

js
function setupLogger() {
  // Dòng 2: Sử dụng config trước khi khai báo
  const level = config && config.level; // var: undefined (hoisted); let: ReferenceError (TDZ)

  log("Logger initialized");

  function log(message) {
    console.log(`[${level || "info"}] ${message}`);
  }

  var config = getConfig(); // ← refactor từ var sang let ở đây
}

Reproduction (Tái hiện lỗi): Khi đổi var config = getConfig() thành let config = getConfig(), dòng const level = config && config.level throw ReferenceError: Cannot access 'config' before initialization.

Evidence (Bằng chứng):

  • Stack trace chỉ dòng const config = getConfig().
  • Code hoạt động bình thường với var.

Hypothesis (Giả thuyết):

  • let config ở cuối function được declare trong Creation Phase của setupLogger, đưa binding vào TDZ từ đầu function body.
  • Dòng 2 const level = config && config.level cố gắng đọc binding config đang trong TDZ (uninitialized).
  • Với var, binding được initialize thành undefined trong Creation Phase, nên config && config.level trả về undefined và code chạy — dù behavior có thể sai (dùng default level thay vì config thực).

Verification (Xác minh): Di chuyển let config = getConfig() lên trước dòng sử dụng:

js
function setupLogger() {
  let config = getConfig(); // Khai báo + initialize trước khi dùng

  const level = config && config.level;
  log("Logger initialized");

  function log(message) {
    console.log(`[${level || "info"}] ${message}`);
  }
}

Code chạy. Giả thuyết đúng: lỗi là do đọc binding trong TDZ.

Root Cause (Nguyên nhân gốc rễ): Developer nghĩ var config; ở cuối function là "khai báo dự phòng" và refactor sang let config; với cùng intent. Họ không nhận ra let trong cùng scope sẽ đưa binding vào TDZ từ đầu function, ảnh hưởng đến tất cả code trước dòng khai báo.

Fix (Sửa): Xóa dòng var config; hoàn toàn vì config đã được khai báo bằng const ở đầu function.

Prevention (Phòng ngừa):

  • Khi refactor var → let/const, kiểm tra xem có khai báo trùng tên trong cùng scope không.
  • ESLint rule no-redeclare và no-use-before-define có thể bắt lỗi này.

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

Depth L3–L4: Debug Decision (Quyết định gỡ lỗi)

Bạn nhận được bug report với stack trace sau:

js
// Bug report với stack trace sau:
// ReferenceError: Cannot access 'db' before initialization
//     at connectDatabase (/app/db.js:12:18)

// Code:
function connectDatabase() {
  const config = loadConfig();

  // Dòng 12
  const connection = createConnection(db.host, db.port);

  // Dòng 15 — junior developer thêm ở cuối function vì thói quen "khai báo cuối" từ var
  let db = config.database;
}

Câu hỏi:

  1. Tại sao lỗi xảy ra ở dòng 12 khi let db ở dòng 15?
  2. Tại sao message là "Cannot access 'db' before initialization" thay vì "db is not defined"?
  3. Bạn sẽ fix như thế nào?
[Đáp án tham khảo]
  • Bạn nghĩ

    • Dòng 15 let db được declare trong Creation Phase của connectDatabase, đưa binding vào TDZ từ đầu function body.
    • Dòng 12 createConnection(db.host, db.port) cố gắng đọc binding db đang trong TDZ (uninitialized) → throw ReferenceError.
    • Message là "Cannot access 'db' before initialization" vì binding đã tồn tại trong Environment Record nhưng chưa initialize. Khác với "db is not defined" — đó là khi binding không tồn tại trong bất kỳ scope nào.
  • Giải thích chính xác

    • let db ở cuối function vẫn được xử lý trong Creation Phase. Từ đầu function, db đã tồn tại nhưng ở trạng thái uninitialized.
    • Dòng 12 chạy trong Execution Phase, trước khi dòng 15 initialize binding → TDZ error.
    • Với var db = config.database, binding được initialize thành undefined trong Creation Phase, nên dòng 12 sẽ đọc undefined.host → TypeError (hoặc silent bug tùy implementation).
  • Fix

    • Di chuyển let db = config.database; lên trước dòng 12:

      js
      function connectDatabase() {
        const config = loadConfig();
        let db = config.database; // Initialize trước khi dùng
      
        const connection = createConnection(db.host, db.port);
      }
  • Trade-off

    • Junior developer thêm let db ở cuối vì thói quen từ var (hoisted). Với let/const, declaration location quan trọng vì TDZ bắt đầu từ đầu scope, không phải từ dòng khai báo.

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

Bạn đang review PR refactor một file config từ var sang const:

js
// Trước
var API_URL = "https://api.example.com";
var TIMEOUT = 5000;

function init() {
  console.log(API_URL);
  var API_URL = "https://api.staging.com";
}

// Sau
const API_URL = "https://api.example.com";
const TIMEOUT = 5000;

function init() {
  console.log(API_URL);
  const API_URL = "https://api.staging.com";
}

Câu hỏi:

  1. Code trước in ra gì? Tại sao?
  2. Code sau in ra gì? Tại sao?
  3. Developer nghĩ gì sai khi refactor?
[Đáp án tham khảo]
  • Code trước: In undefined. Vì var API_URL trong init được hoisted (declare + initialize undefined trong Creation Phase), shadow biến global. console.log đọc local undefined.
  • Code sau: Throw ReferenceError: Cannot access 'API_URL' before initialization. Vì const API_URL trong init được declare trong Creation Phase nhưng chưa initialize. console.log chạy trong TDZ.
  • Sai lầm: Developer nghĩ const chỉ là "var không đổi". Họ không nhận ra const còn thay đổi initialization timing và tạo TDZ. Ngoài ra, dùng cùng tên API_URL cho cả global và local là bad practice dù với var hay const.

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

Level C — Delegate & Inspect (Giao phó & Kiểm tra)

  1. Tự trả lời trước: Viết ra giấy định nghĩa TDZ của bạn. Bao gồm:

    • TDZ là gì (trạng thái hay thời gian)?
    • TDZ bắt đầu và kết thúc khi nào?
    • typeof behavior với TDZ vs biến không tồn tại?
  2. Hỏi AI: "Explain Temporal Dead Zone in JavaScript. Why does typeof throw an error for TDZ variables but return 'undefined' for undeclared variables?"

  3. So sánh: AI có nói TDZ là "time period" không? Nó có giải thích rõ sự khác biệt giữa 2 loại ReferenceError không?

  4. Verify: Kiểm tra bằng MDN (từ khóa: Temporal Dead Zone, let, typeof) hoặc ECMAScript spec.

Gợi ý

Để ý xem AI có nói "TDZ is the time before the variable is declared" không. Nếu có, đó là dấu hiệu mental model của AI đang dùng approximation thay vì engine mechanism. Bạn đã học rằng TDZ là trạng thái uninitialized của binding, không phải "khoảng thời gian".

Đáp án tham khảo
  • Bạn nghĩ

    • TDZ là trạng thái uninitialized của binding trong Environment Record.
    • Bắt đầu: từ đầu lexical scope chứa binding.
    • Kết thúc: tại dòng khai báo let/const/class.
    • typeof với undeclared: "undefined" (binding không tồn tại).
    • typeof với TDZ: ReferenceError (binding tồn tại nhưng uninitialized).
  • AI trả lời (mô phỏng phản hồi thực tế)

    • "Temporal Dead Zone is the period between the start of a block and the variable declaration where you cannot access the variable."
    • "During TDZ, accessing the variable throws a ReferenceError."
    • "typeof returns 'undefined' for variables that don't exist, but throws for TDZ variables because the variable technically exists in the scope."
    • "This happens because let and const are hoisted to the top of the block but not initialized."
  • So sánh

    • AI đúng về behavior: TDZ throw error, typeof khác nhau giữa undeclared và TDZ.
    • AI thiếu depth: Nó vẫn dùng "period" / "time" để mô tả TDZ. Nó không nhấn mạnh rằng TDZ là trạng thái của binding trong Environment Record.
    • AI nói "hoisted to the top of the block" — lại dùng "hoisted" như cơ chế.
  • Điểm AI nói sai hoặc quá mơ hồ

    • AI nói "TDZ is the period between..." — câu này gây hiểu nhầm TDZ là thời gian. Thực tế, nếu engine pause giữa Creation Phase và Execution Phase trong 1 giây hay 1 năm, TDZ vẫn là cùng một trạng thái.
    • AI nói "let and const are hoisted" — cách diễn đạt này dễ gây nhầm lẫn với var hoisting.
  • Kết luận

    • Nếu bạn chỉ ra được rằng TDZ là trạng thái uninitialized chứ không phải khoảng thời gian, và typeof behavior khác nhau vì một cái là "binding không tồn tại" còn một cái là "binding tồn tại nhưng chưa initialize", bạn đã hiểu sâu hơn AI. Concept này sẽ quay lại ở Stage 2 (Object mutation), Stage 3 (Async callbacks), và Stage 8 (React stale closure).

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

Yêu cầu: Giải thích cho một đồng nghiệp junior trong 2 phút:

"Tôi có hai đoạn code. Đoạn A throw ReferenceError: x is not defined. Đoạn B throw ReferenceError: Cannot access 'x' before initialization. Tại sao message khác nhau? Đoạn nào là TDZ? Dùng đúng terminology: binding, Environment Record, uninitialized. Không được dùng từ 'hoisted'."

js
// Đoạn A
console.log(ghost);

// Đoạn B
console.log(spirit);
let spirit = 1;
Mô phỏng
  • Bạn nói
    • "Cả hai đều là ReferenceError, nhưng nguyên nhân hoàn toàn khác nhau."
    • "Đoạn A: ghost không tồn tại trong bất kỳ Environment Record nào. Engine tìm từ inner scope ra outer scope rồi global — không thấy binding nào tên ghost. Kết quả: ReferenceError: ghost is not defined."
    • "Đoạn B: spirit đã tồn tại trong Environment Record. Engine tìm thấy binding spirit trong block scope. Nhưng binding này ở trạng thái uninitialized — nó đã được declare trong Creation Phase nhưng chưa được initialize."
    • "Khi engine cố đọc một binding uninitialized, nó throw ReferenceError: Cannot access 'spirit' before initialization. Đây chính là Temporal Dead Zone."
    • "Điểm then chốt: TDZ không phải là 'thời gian chờ'. Nó là trạng thái của binding. Binding đã tồn tại nhưng chưa sẵn sàng để dùng."
    • "Nếu đồng nghiệp hỏi 'vậy làm sao sửa?', câu trả lời đơn giản: đừng đọc biến trước dòng khai báo."

💡 Liên tưởng (Analogy — dùng ở L2–L3): Tưởng tượng một căn phòng. Đoạn A là bạn gõ cửa phòng không tồn tại — không ai trả lời. Đoạn B là bạn gõ cửa phòng có người, nhưng người đó chưa mặc quần áo xong — họ hét "Đợi đã!" (ReferenceError). Cả hai đều không cho bạn vào, nhưng lý do hoàn toàn khác nhau.

Lưu ý: Đây là analogy để phân biệt "binding không tồn tại" vs "binding uninitialized". Ở level cao hơn (S11+), bạn cần reasoning trực tiếp qua Environment Record và spec algorithm thay vì analogy.

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

  • Đồng nghiệp có hiểu tại sao typeof ghost trả về "undefined" nhưng typeof spirit throw error không?
  • Bạn có thể dự đoán được behavior nếu thêm var spirit; ở đầu scope không?
  • Nếu đồng nghiệp hỏi "TDZ kéo dài bao lâu?", bạn trả lời được không mà không dùng từ "thời gian"?

15. Assessment (Đánh giá) ​

Objective (Mục tiêu)Hình thức đánh giáDepth
Giải thích TDZ là trạng thái uninitializedExplain (Giải thích) + Teach BackL2–L3
Phân biệt TDZ error vs undeclared errorPrediction (Dự đoán) + DebugL3–L4
Dự đoán typeof behavior với TDZPrediction (Dự đoán)L3
Debug bug TDZ khi refactor var → letDebug Lab (Gỡ lỗi)L4
Trace TDZ qua Creation/Execution PhaseWorked Example + PredictionL3–L4

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

  • [ ] Có thể giải thích Temporal Dead Zone là trạng thái uninitialized của binding, không phải khoảng thời gian.
  • [ ] Có thể phân biệt ReferenceError: x is not defined (binding không tồn tại) và ReferenceError: Cannot access 'x' before initialization (binding trong TDZ).
  • [ ] Có thể dự đoán typeof behavior: "undefined" cho undeclared, ReferenceError cho TDZ.
  • [ ] Có thể trace TDZ qua Creation Phase và Execution Phase cho let, const, và class.
  • [ ] Có thể debug bug TDZ trong code refactor từ var sang let/const.
  • [ ] Có thể dự đoán đúng 3/3 scenarios trong Prediction Exercise mà không chạy code.

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

Previous (Trước): let/const → bạn đã biết cả hai đều là block-scoped bindings được declare trong Creation Phase nhưng không initialize cho đến dòng khai báo.

Current (Hiện tại): Temporal Dead Zone → bạn hiểu rằng TDZ là trạng thái uninitialized của binding trong Environment Record, và sự khác biệt giữa "binding không tồn tại" và "binding tồn tại nhưng chưa initialize".

Next (Tiếp theo):

  • 1.3.5 (Hoisting không phải một cơ chế duy nhất): Tổng hợp behavior của var, let, const, function, class — mỗi loại có declaration và initialization timing khác nhau.
  • 1.3.6 (Hoisting trong Function): So sánh var và let trong cùng một function bằng environment model.
  • 1.4 (Closure): Closure giữ reference đến Environment Record. Để hiểu stale closure và memory retention, bạn cần biết binding trong environment đã ở trạng thái nào — initialize hay uninitialized.
📴 Offline Mode — Content served from cache