Closures
Closures can feel like a complex topic, but they’re actually quite straightforward once you get the hang of them. Imagine closures as a backpack that a function carries with it, containing all the variables it had access to when it was created. “When it was created” is a key phrase here.
The Backpack
Here’s some code:
function outerFunction() {
let count = 0; // This is the backpack
return function innerFunction() {
count++;
console.log(count);
};
}
const counter = outerFunction();
counter(); // Logs: 1
counter(); // Logs: 2
What’s happening here?
When outerFunction
runs, it creates count
and then returns innerFunction
. But here’s the magic: innerFunction
remembers count
, even after outerFunction
has finished running. This “memory” is the closure.
Think of closures as a vending machine. When you deposit a coin (call outerFunction
), the machine remembers your balance (closure) even if you walk away. When you return, the machine still knows how much you’ve deposited.
The ECMAScript specification describes closures as a combination of a function and its lexical environment (the variables available when the function was defined). This environment travels with the function wherever it’s used.