JavaScript Closures Explained: Why Your Functions Remember Everything

javascript dev.to

Read the full article here

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.
  • var vs let in loopsvar shares a single variable; let creates 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.



Enter fullscreen mode Exit fullscreen mode

Source: dev.to

arrow_back Back to Tutorials