JavaScript Interview Prep
Closure & Hoisting Gotchas
Master Closure and Hoisting gotchas in JavaScript. Learn how lexical environments, variable shadowing, and memory retention cause common interview pitfalls.
1. Introduction
Closures and Hoisting are fundamental scope mechanisms in JavaScript. While powerful, subtle edge cases (like variable shadowing, shared variable references in loops, and function declaration hoisting order) frequently catch developers off guard during technical interviews.
2. Essential Gotchas & Code Scenarios
Gotcha 1: Variable Shadowing inside Closures
let x = 10;function createAdder(x) { return function(y) { return x + y; // Which x is referenced here? }; }
const addFive = createAdder(5); console.log(addFive(2));
View Output & Explanation
Output: 7
Explanation: The parameter x of createAdder(5) shadows the outer global let x = 10. The inner closure captures parameter x = 5, evaluating 5 + 2 = 7.
Gotcha 2: Hoisting Order between Var and Function Declarations
console.log(typeof myFunc);var myFunc = 'Hello';
function myFunc() { return 'World'; }
console.log(typeof myFunc);
View Output & Explanation
Output: "function", then "string"
Explanation: Function declarations hoist before var declarations during memory allocation. So initially, myFunc is a function. However, when execution reaches var myFunc = 'Hello', the assignment overwrites the identifier with string "Hello".
Gotcha 3: Encapsulating Private State via Closures
function createCounter() { let count = 0; return { increment() { count++; return count; }, decrement() { count--; return count; } }; }const c1 = createCounter(); const c2 = createCounter();
console.log(c1.increment()); console.log(c1.increment()); console.log(c2.increment());
View Output & Explanation
Output: 1, 2, 1
Explanation: Each call to createCounter() creates a fresh lexical environment. c1 and c2 maintain completely separate, isolated count variables in memory.
3. Quick Quiz
Q1: What happens if a function declaration and a var declaration share the same name in the same scope?
A) The engine throws a SyntaxError: Duplicate identifier
B) The function declaration hoists first; var assignments overwrite the binding when evaluated
Answer: B — Function declarations take hoisting precedence over var declarations, but variable assignment statements overwrite the reference at runtime.
4. Production Considerations
- • Avoid Leaking Closure Memory: Closures keep all outer scope variables referenced in their environment alive. Unsubscribe or release heavy closures when components unmount to prevent memory leaks.