JavaScript Variable Hoisting & Temporal Dead Zone (TDZ)

If you've ever wondered why JavaScript sometimes throws a ReferenceError
even though your variable is declared โ you're not alone. The answer lies in two concepts: hoisting and the Temporal Dead Zone (TDZ).
๐ง What is Hoisting?
Hoisting is JavaScript's behavior of moving variable and function declarations to the top of their scope during the compilation phase โ before your code actually runs.
But not all declarations are treated the same way.
๐ Hoisting in var
, let
, and const
Declaration | Hoisted? | Initialized During Hoisting? | Access Before Declaration |
var | โ Yes | โ
Yes (undefined ) | โ
Allowed (returns undefined ) |
let | โ Yes | โ No (in TDZ) | โ ReferenceError |
const | โ Yes | โ No (in TDZ) | โ ReferenceError |
๐ Example
// Variable x is declared using var
// so it is hoisted and is initialized with value undefined. Accessing x before the initialization results in undefind.
console.log("x is", x);
var x = 10;
console.log("x is", x);
// No difference between above code
console.log("y is", y);
var y;
y = 20;
console.log("y is", y);
// Variable z is declared using let
// console.log("z is", z); ReferenceError: Cannot access 'z' before initialization. At this line z is in TDZ . It is hoisted but uninitialized.
let z = 30;
console.log("z is", z);
// Variable t is declared using const
// console.log("t is", t); ReferenceError: Cannot access 't' before initialization At this line t is in TDZ . It is hoisted but uninitialized.
const t = 40;
console.log("t is", t);
// console.log("p is", p); ReferenceError: Cannot access 'p' before initialization
let p; // Here we declare variable p using but we did not initialize it , in this case it is initialized with value undefined. at this line TDZ ends since declaration happened.
console.log("p is", p); // It is possible to access p now but it results in undefined
p = 50;
console.log("p is", p);
// Remember, variables are hoisted but only to the top of the scope they were declared in. Here x is hoised in function scope
function abc() {
console.log(x);
let x = 20;
}
// abc(); ReferenceError: Cannot access 'x' before initialization
function xyz() {
console.log("x is inside function, hoisted as", x);
var x = 20;
}
xyz();
{
console.log("a is inside block , hoised as", a);
var a = 50;
}
๐ฅ What is the Temporal Dead Zone (TDZ)?
The TDZ is the phase between the start of a block and the actual declaration of a let
or const
variable.
During this phase:
The variable exists
But is unreachable
Any access results in a ReferenceError
โ Safe Usage
let name;
console.log(name); // undefined
name = "Pushpesh";
- TDZ ends after the
let
line, so this works fine.
โ Final Takeaways
Hoisting lifts declarations โ but not the values.
var
is function-scoped and initialized withundefined
let
andconst
are block-scoped and live in a TDZ until declared.Always declare variables before using them to avoid unexpected errors.
Subscribe to my newsletter
Read articles from pushpesh kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
