Introduced in ES6.
- Block-scoped → only accessible within the
{}where they're defined. - Hoisted but not initialized → lives in the Temporal Dead Zone until the declaration line.
- Can be updated but not re-declared in the same scope.
Example:
{
let a = 10;
a = 20; // ✅ allowed
// let a = 30; // ❌ SyntaxError: Identifier 'a' has already been declared
}- Also block-scoped.
- Hoisted but not initialized → in TDZ until declaration.
- Must be initialized at the time of declaration.
- Cannot be reassigned, but object/array properties can still be mutated.
Example:
{
const b = 50; // ✅ must initialize
// b = 60; // ❌ TypeError
const obj = { x: 1 };
obj.x = 2; // ✅ allowed
}Definition:
The period between entering a scope (block/function) and the actual declaration of a let or const variable — during which the variable exists but cannot be accessed.
- Variables in TDZ are hoisted, but not given a default value (
undefined). - Accessing them before declaration →
ReferenceError. - Prevents accidental usage of variables before initialization.
Example:
console.log(x); // ReferenceError (TDZ)
let x = 5;
console.log(x); // 5- Makes code more predictable.
- Helps catch errors where variables are used before being properly initialized.
| Feature | var | let | const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Hoisted? | Yes | Yes | Yes |
| Initialized on hoist? | Yes (undefined) |
No (TDZ) | No (TDZ) |
| Redeclaration allowed? | Yes | No | No |
| Reassignment allowed? | Yes | Yes | No |
"Both
letandconstare block-scoped and hoisted, but unlikevar, they're not initialized until the actual declaration line — the period before that is the Temporal Dead Zone.letcan be reassigned but not redeclared, whileconstmust be initialized and can't be reassigned, though its object properties can be changed."