Skip to main content

Command Palette

Search for a command to run...

Hoisting

Published
3 min read

Var vs Let vs Const

Featurevarletconst
ScopeFunctionBlockBlock
HoistedYesYes (TDZ)Yes (TDZ)
Initialized on hoistYesNoNo
Re-declarationYesNoNo
Re-assignmentYesYesNo
Global objectYesNoNo

First, the Mental Model (Critical)

Before definitions, you must understand how JavaScript executes code.

JavaScript execution happens in two phases:

Phase 1: Memory Creation Phase

  • Variables are allocated memory

  • Function declarations are stored entirely

  • No code is executed

Phase 2: Execution Phase

  • Code runs line by line

  • Variables get assigned actual values

Hoisting happens in Phase 1.

What Is Hoisting?

Hoisting is JavaScript’s behavior of moving variable and function declarations to the top of their scope during the memory creation phase.

Important clarification:

  • Only declarations are hoisted

  • Assignments are NOT hoisted

Hoisting with var

Example

console.log(a);
var a = 10;

What You See

undefined

What Actually Happens Internally

Memory Creation Phase

var a; // initialized with undefined

Execution Phase

console.log(a); // undefined
a = 10;

✔ This is why var gives undefined, not an error.

Hoisting with let and const (Key Difference)

console.log(b);
let b = 20;

Output:

ReferenceError: Cannot access 'b' before initialization

❗ Important:

  • let and const ARE hoisted

  • But they are NOT initialized

This leads us to the Temporal Dead Zone.

Temporal Dead Zone (TDZ) — Proper Definition

The Temporal Dead Zone is:

The time between scope creation and variable initialization during which accessing the variable throws a ReferenceError.

TDZ applies to:

  • let

  • const

  • class

Visualizing TDZ

{
  // TDZ starts
  console.log(x); // ❌ ReferenceError
  let x = 10;
  // TDZ ends
}

Timeline:

Scope created ──▶ TDZ ──▶ Initialization ──▶ Usage allowed

Why TDZ Exists (Interview Gold)

TDZ was introduced to:

  • Prevent bugs caused by accessing variables before declaration

  • Enforce clean, predictable code

  • Replace unsafe var behavior

Interview-grade explanation:

“TDZ ensures variables are used only after they are declared, preventing logical errors.”

Global Scope Behavior (Browser-Specific Question)

var a = 10;
let b = 20;

console.log(window.a); // 10
console.log(window.b); // undefined

Explanation:

  • var attaches to the global object

  • let and const do NOT

This prevents accidental global pollution.

Loop Behavior (Very Common Interview Trap)

Using var

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}

Output:

3 3 3

Using let

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}

Output:

0 1 2

Why?

  • let creates a new block scope per iteration