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
var
ES5 Legacy
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
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
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, 2Interview-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: