Suggest an editImprove this articleRefine the answer for “Temporal dead zone (TDZ)”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**The TDZ (temporal dead zone) is the stretch from the start of a variable's scope to the moment it is actually initialised, during which the variable cannot be touched.** Inside that "dead zone" the variable already exists, the engine registered it while creating the lexical environment, but it has no value yet, so any access throws a `ReferenceError`. The TDZ applies to `let`, `const` and `class`: they are hoisted too, but unlike `var` they are not initialised to `undefined`. Even `typeof`, which is safe for an undeclared variable, throws inside the TDZ. The point of the mechanism is predictability: it stops you using a variable before it is genuinely ready. ```javascript console.log(x); // undefined (var is hoisted and initialised) var x = 10; console.log(y); // ReferenceError: Cannot access 'y' before initialization let y = 20; ``` **Key point:** in the TDZ the variable already exists but is not yet initialised, and reading it is a `ReferenceError`.Shown above the full answer for quick recall.Answer (EN)Image**The TDZ (temporal dead zone) is the stretch of time from the start of a variable's scope to the moment it is actually initialised, during which the variable cannot be accessed.** Put simply, it is a "dead zone" in which the variable already exists (the engine has registered it) but has not been initialised yet, so trying to use it raises an error. ## Theory ### TL;DR - The TDZ is the period between creating a variable's binding and initialising it. - It applies to `let`, `const` and `class`. - Accessing a variable inside its TDZ throws a `ReferenceError`. - `var` is hoisted too, but it is initialised to `undefined` straight away, so it has no TDZ. - `typeof` does not save you in the TDZ: it throws a `ReferenceError` as well. - Every block `{ ... }` creates its own scope and therefore its own TDZ. - The purpose is safety and predictability: you cannot use a variable before it is declared. ### Quick example ```javascript console.log(a); // ReferenceError let a = 10; ``` What happens: 1. JavaScript **knows** `a` exists before the code runs, at the point where the lexical environment is created. 2. But until the line `let a = 10;`, the variable sits in the **TDZ**. 3. Any attempt to touch it in that zone throws a **ReferenceError**. ### How it differs from `var` ```javascript console.log(x); // undefined var x = 10; console.log(y); // ReferenceError let y = 20; ``` The difference: - `var` variables are **hoisted** and **initialised** with `undefined`; - `let` and `const` are **hoisted as well**, but **not initialised**, and until initialisation they sit in the **TDZ**. So hoisting applies to both forms; what differs is whether the binding gets a starting value. ### The TDZ inside a block ```javascript let a = 1; { // the TDZ for b starts here console.log(a); // 1 // console.log(b); // ReferenceError let b = 2; // end of the TDZ console.log(b); // 2 } ``` Every block `{ ... }` creates a **new scope**, and the `let` and `const` variables inside it have their own dead zone up to their initialisation. The same holds inside a function: the TDZ is in force from the moment you enter its scope until the declaration line. ```javascript function foo() { console.log(bar); // ReferenceError let bar = "Hello"; } foo(); ``` ### The TDZ and `typeof` The `typeof` operator is safe for a variable that does not exist at all, but it does not help in the TDZ. ```javascript console.log(typeof x); // "undefined" console.log(typeof y); // ReferenceError let y = 10; ``` This is one of the very few situations where `typeof` throws: for a completely undeclared name it returns `"undefined"`, while for a name in the TDZ it raises an error. ### The TDZ and `class` Classes obey the TDZ too: ```javascript const obj = new MyClass(); // ReferenceError class MyClass {} ``` A class declaration **is hoisted**, but it sits in the **TDZ** until its declaration line, exactly like `let` and `const`. That is why a class, unlike a function declaration, cannot be used above the place where it is declared. ### Why it exists The TDZ is a safety and predictability mechanism. It stops you using a variable **before it is genuinely ready**. If `let` behaved like `var`, it would be easy to hit unpredictable bugs caused by `undefined` that surface far away from their real cause. With the TDZ, the error appears exactly where the problem is. Visually: ```javascript { // the variable already exists in memory, but is unreachable: this is the TDZ console.log(x); // ReferenceError let x = 5; // end of the TDZ, the variable is initialised console.log(x); // 5 } ``` ### Summary | Feature | Description | | --- | --- | | What the TDZ is | The period between creating a variable and initialising it | | Where it appears | For `let`, `const`, `class` | | What happens on access | `ReferenceError` | | Why it exists | It prevents using variables before their declaration | | Difference from `var` | `var` is initialised to `undefined`, `let`/`const` are not | ### Common mistakes - Saying that `let` and `const` "are not hoisted". They are hoisted, they are just not initialised, and that is precisely what creates the TDZ. - Relying on `typeof` as a safe check. For a variable in the TDZ it throws a `ReferenceError`. - Confusing `ReferenceError: Cannot access 'y' before initialization` (the TDZ) with `ReferenceError: y is not defined` (no such variable at all). - Using a class above its declaration on the assumption that it behaves like a function declaration. Classes have a TDZ. - Forgetting that the TDZ is tied to **position in the code**, not to time: a function call written above the declaration but executed later works fine.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.