JavaScript Closures Explained
Closures are functions that remember variables from their outer scope, even after the outer function returns. Understanding them solves common issues like the var loop bug, stale React hooks, and memory leaks.
Key Points
- Closures capture references, not values – functions hold pointers to variables, not snapshots.
- Lexical scope – what a function can access is determined by where it is written in the code, not where it is called.
-
varvsletin loops –varshares a single variable;letcreates a new binding per iteration. -
React hooks and stale closures – closures can capture old state. Fix with dependency arrays or
useRef. - Memoization – closures can store results for performance optimization.
- Memory leaks – closures keep references alive. Always clean up event listeners and timers.
Example: Counter
javascript
function makeCounter() {
let count = 0; // closure keeps this alive
return function increment() {
count++;
return count;
};
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
counter(); // 3
Closures allow `count` to persist even after `makeCounter` has returned.
**React Stale Closure Fix**
`useEffect(() => {
const id = setInterval(() => fetchResults(query), 2000);
return () => clearInterval(id);
}, [query]); // dependency array ensures fresh state`
Closures are everywhere in JavaScript, understanding them is essential to write predictable and efficient code.
Top comments (0)