I avoided closures for longer than I care to admit.
Not deliberately. I just kept telling myself I understood them because I could repeat the usual line: “a closure is a function that remembers its lexical scope.” That sentence sounds convincing. It is also not enough.
Closures only really make sense once you stop treating them as a concept to memorise and start seeing them as a behaviour your code exhibits.
This article is not a definition dump. It is an attempt to explain closures the way they actually show up in real JavaScript code and why they matter far more than most beginners realise.
A closure is not created when you write a function
This is where most explanations subtly mislead people.
Closures are not created when a function is declared. They emerge when a f…
I avoided closures for longer than I care to admit.
Not deliberately. I just kept telling myself I understood them because I could repeat the usual line: “a closure is a function that remembers its lexical scope.” That sentence sounds convincing. It is also not enough.
Closures only really make sense once you stop treating them as a concept to memorise and start seeing them as a behaviour your code exhibits.
This article is not a definition dump. It is an attempt to explain closures the way they actually show up in real JavaScript code and why they matter far more than most beginners realise.
A closure is not created when you write a function
This is where most explanations subtly mislead people.
Closures are not created when a function is declared. They emerge when a function is executed and continues to reference variables from an outer scope that would otherwise be gone.
Consider this:
function createCounter() {
let count = 0;
return function () {
count++;
return count;
};
}
const counter = createCounter();
At first glance, it looks like ==count== should disappear as soon as ==createCounter== finishes running. But it does not. The inner function still has access to it.
Why?
Because JavaScript does not copy values into functions. It keeps references to the environment in which the function was created.
That environment, the lexical environment, is what we casually call a closure.
Closures are about memory, not syntax
One of the most useful mental shifts I made was realising that closures are fundamentally a ==memory model==, not a syntax feature.
The JavaScript engine keeps variables alive only as long as something can still reach them.
In the example above:
==count== is still reachable
therefore it stays in memory
therefore its value persists between function calls
That is it. No magic.
Once you see closures this way, a lot of confusing behaviour suddenly becomes predictable.
Why closures feel confusing at first
Closures are hard because they break an intuitive rule many people unconsciously follow:
“When a function finishes, everything inside it disappears.”
That rule is mostly true, until it is not.
Closures are the exception that proves the rule. They force you to think about ==who still has a reference== to what.
This is also why closures are a common source of bugs, especially in loops.
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i);
}, 1000);
}
People expect ==0, 1, 2==.
They get ==3, 3, 3==.
Not because JavaScript is broken, but because all three functions close over the ==same variable==, not three different values.
Once you understand closures, this behaviour stops being surprising.
Closures are everywhere, even when you do not notice them
If you have ever:
- used ==useState= in React
- written a callback
- used ==setTimeout== or ==setInterval==
- worked with event listeners
- implemented currying or partial application
you have already used closures.
Frameworks lean heavily on closures because they allow state to exist without global variables. That is an enormous design advantage.
React hooks, for example, rely on closures to “remember” values between renders while still keeping functions pure in appearance.
Closures enable encapsulation without classes
Before ES6 classes became popular, closures were one of the main ways to create private state in JavaScript.
Even today, many developers prefer closures over classes for simple encapsulation:
function createBankAccount() {
let balance = 0;
return {
deposit(amount) {
balance += amount;
},
getBalance() {
return balance;
}
};
}
Here, ==balance== is completely inaccessible from the outside. There is no keyword for privacy. The privacy emerges naturally from the closure.
This pattern still holds up remarkably well.
The downside: closures can keep things alive too long
Closures are powerful, but they are not free.
Because closures keep references alive, they can accidentally keep large objects in memory longer than necessary. This is especially relevant in long-running applications like browsers or servers.
Memory leaks caused by closures are subtle and often misunderstood. The problem is not closures themselves, but forgetting that what you reference stays alive.
Understanding closures helps you reason about memory usage far better than memorising garbage collection rules.
A better way to explain closures (in one sentence)
If I had to explain closures in one sentence now, it would be this:
A closure is what happens when a function keeps a live connection to variables that existed when it was created.
That sentence is not poetic, but it is accurate.
Reading further and deepening your understanding
If you want to go deeper, here are some genuinely useful directions to explore:
MDN’s explanation of lexical environments and execution contexts
Articles that explore JavaScript engine internals (V8 in particular)
Functional programming discussions on closures in Scheme and Lisp
Academic papers on lexical scoping and environment models (arXiv is useful here)
Closures are not unique to JavaScript. Understanding them well makes learning other languages easier.
Final thoughts
Closures are not something you “learn once”.
They are something you gradually notice more clearly the longer you write JavaScript.
At some point, they stop being a mysterious interview topic and start becoming a quiet, dependable tool you rely on without thinking.
And that is usually the sign that you finally understand them.