Skip to content
GeeksSmith
beginner 5 min read

Scope, Hoisting & Temporal Dead Zone

Hoisting is JavaScript's compilation phase behavior where variable and function declarations are registered into memory within their lexical scope before any line of code executes.

Why it matters in interviews

Understanding the Temporal Dead Zone (TDZ), execution contexts, and lexical vs function scoping prevents subtle runtime reference bugs and demonstrates core language mastery.

Visual & Interactive Explanation

var vs let vs const Comparison Matrix

Interactive Comparison

var

ES5 Legacy

Function Scope
ScopeFunction or Global
HoistingHoisted & initialized to undefined
TDZNo TDZ (returns undefined)
Re-declarationAllowed (danger)
Strengths
  • Legacy compatibility
Trade-offs
  • Pollutes outer scopes
  • No block boundary

let

ES6 Mutable

Block Scope
ScopeBlock Scope { ... }
HoistingHoisted uninitialized into TDZ
TDZThrows ReferenceError
Re-declarationDisallowed in same scope
Strengths
  • Safe loop counters
  • Prevents scope leaks
Trade-offs
  • Allows reassignment (mutable)

const

ES6 Immutable Binding

Preferred Default
ScopeBlock Scope { ... }
HoistingHoisted uninitialized into TDZ
ReassignmentDisallowed (TypeError)
MutationObject properties can still mutate
Strengths
  • Immutable binding
  • Clear intent for readability
Trade-offs
  • Does not deeply freeze objects (use Object.freeze)

Code Examples & Implementation

Temporal Dead Zone (TDZ) in Action
{
  // Start of TDZ for 'value'
  // console.log(value); // ❌ Throws ReferenceError: Cannot access 'value' before initialization

  const temp = "hello";
  
  let value = 42; // End of TDZ for 'value'
  console.log(value); // ✅ 42
}
Classic Loop Closure with var vs let
// ❌ Using var (one shared function-scoped variable)
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log('var:', i), 100);
}
// Logs: 3, 3, 3

// ✅ Using let (fresh block-scoped binding per iteration)
for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log('let:', j), 100);
}
// Logs: 0, 1, 2

Interview-Ready Answers

`var` is function-scoped and hoisted initialized to `undefined`. `let` and `const` are block-scoped and hoisted uninitialized into the Temporal Dead Zone (TDZ), throwing a `ReferenceError` if accessed before declaration.

Official Documentation & Specifications

Follow-up Questions & Deep Dives

🎯 Code Output — What Does This Print?

Question 1easy
console.log(a);
var a = 5;
console.log(a);
Question 2medium
console.log(typeof x);
let x = 10;
Question 3medium
greet();
function greet() { console.log("Hello"); }

farewell();
var farewell = function() { console.log("Bye"); };
Question 4tricky
const obj = { a: 1 };
obj.b = 2;
obj.a = 99;
console.log(obj);
Question 5hard
var x = 1;
function foo() {
  console.log(x);
  if (true) {
    var x = 2;
  }
  console.log(x);
}
foo();

Common Mistakes & Anti-Patterns

  • Thinking `let` and `const` are not hoisted (they are hoisted into the TDZ)
  • Assuming `const` deeply freezes objects or arrays
  • Using `var` in asynchronous loop callbacks

Real-World Architectural Scenario

Why does a codebase refactored from `var` to `let`/`const` catch previously undetected bugs?

Rate Your Readiness

Rate how comfortably you can explain this in an interview to update your global readiness gauge:

Rate your confidence: