Closures & Scopeeasy
Explain closures — and the classic loop bug
What is a closure? Demonstrate the classic `var` loop bug and fix it using a closure, `let`, or IIFE.
Asked at Google, Meta, Amazon, Airbnb
Answer
// Usage // A closure is a function that retains access to its outer // (enclosing) scope even after the outer function has returned. function makeCounter() { let count = 0 // captured by the returned function return () => ++count // this is the closure } const counter = makeCounter() counter() // 1 counter() // 2 // ───────────────────────────────────────────────────────── // Classic loop bug with var for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100) } // Prints: 3, 3, 3 — all share the same 'i' variable // Fix 1: use let (block-scoped, new binding per iteration) for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100) } // Prints: 0, 1, 2 // Fix 2: IIFE to capture each value for (var i = 0; i < 3; i++) { (function(j) { setTimeout(() => console.log(j), 100) })(i) }