JavaScript Variable Hoisting & Temporal Dead Zone (TDZ)

pushpesh kumarpushpesh kumar
3 min read

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

DeclarationHoisted?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 with undefined

  • let and const are block-scoped and live in a TDZ until declared.

  • Always declare variables before using them to avoid unexpected errors.

0
Subscribe to my newsletter

Read articles from pushpesh kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

pushpesh kumar
pushpesh kumar