Closures
Closures
Section titled “Closures”Introduction
Section titled “Introduction”A closure is a function that remembers the variables from its lexical scope even after the outer function has returned. Closures are one of JavaScript’s most powerful and distinctive features.
Real World Story
Section titled “Real World Story”A closure is like a backpack. When a student leaves a classroom (outer function returns), they still carry their backpack with its contents (closure — variables they had access to).
Visual Explanation
Section titled “Visual Explanation”flowchart TD A["outer() is called"] B["Creates: let count = 0"] C["Returns inner() function"] D["inner() 'remembers' count"] E["Each call to inner increments count"]
A --> B A --> C C --> D D --> E
subgraph Closure B D endBasic Example
Section titled “Basic Example”function createCounter() { let count = 0; // "closed over" variable
return function() { count++; return count; };}
const counter = createCounter();console.log(counter()); // 1console.log(counter()); // 2console.log(counter()); // 3Common Use Cases
Section titled “Common Use Cases”// 1. Data encapsulation (private variables)function createUser(name) { let points = 0;
return { getName: () => name, addPoints: (p) => { points += p; }, getPoints: () => points };}
const user = createUser('Alice');user.addPoints(10);console.log(user.getPoints()); // 10console.log(user.points); // undefined — private!
// 2. Function factoriesfunction multiplyBy(factor) { return (number) => number * factor;}
const double = multiplyBy(2);console.log(double(5)); // 10
// 3. Partial applicationfunction add(x) { return (y) => x + y;}
const add5 = add(5);console.log(add5(3)); // 8Closure in Loops
Section titled “Closure in Loops”// Classic closure problem with varfor (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100);}// 3, 3, 3 — all share the same i
// Fix with closurefor (var i = 0; i < 3; i++) { ((j) => { setTimeout(() => console.log(j), 100); })(i);}// 0, 1, 2
// Modern fix — use letfor (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100);}// 0, 1, 2Memory Considerations
Section titled “Memory Considerations”// Closures keep references to outer variablesfunction createLargeClosure() { const largeArray = new Array(1000000).fill('data');
return function() { console.log('closure still holds reference to largeArray'); };}// The largeArray cannot be garbage collected as long as the closure existsSummary
Section titled “Summary”- A closure is a function + its lexical environment
- Enables data privacy, function factories, and callbacks
- “Remembers” variables even after outer function returns
- Use closures for encapsulation and partial application