The JavaScript Concept That Clicked for Me (Finally)
The one concept every developer struggles with, until they realize it's just a function with memory.
Closures broke my brain for two years.
Two years.
I’d read the definition a hundred times: “A closure is a function that has access to variables from another function’s scope.” Cool. Sounds important. Meant nothing.
I’d see them everywhere in tutorials. People used them like they were obvious. They weren’t.
Then one day, I stopped trying to understand closures in the abstract and just watched them work in real code. And suddenly... it all made sense.
Here’s the thing nobody tells you: closures aren’t magic. They’re just functions with memory.
The Moment It Clicked
I was building a simple counter widget. Nothing fancy:
javascript
function createCounter() {
let count = 0;
return {
increment() { count++; return count; },
decrement() { count--; return count; },
getCount() { return count; }
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.decrement()); // 1Wait. How is count still there? The createCounter() function should be done running. Its variables should be garbage collected, right?
Nope.
The functions inside that object (increment, decrement, getCount) each have a “memory” of the scope they were created in. They remember where count lives. They can access it. They can change it. They carry that scope with them, even after createCounter() finishes executing.
That’s a closure. It’s just a function that remembers its home.
Why This Matters
Once I got that, everything unlocked.
Suddenly I understood why this works:
javascript
function setupButtons() {
for (var i = 0; i < 5; i++) {
const button = document.createElement(’button’);
button.textContent = `Button ${i}`;
button.addEventListener(’click’, function() {
console.log(`You clicked button ${i}`);
});
document.body.appendChild(button);
}
}Each button’s click handler is a closure. It remembers the i value from its birth. That’s why it works (especially with const). Each iteration creates a new scope, a new memory for each handler.
I also finally understood why this is a common gotcha:
javascript
const functions = [];
for (var i = 0; i < 3; i++) {
functions.push(function() { console.log(i); });
}
functions[0](); // 3
functions[1](); // 3
functions[2](); // 3All three functions are closures over the same i. By the time you call them, the loop has finished and i is 3. All of them remember the same i. This is why everyone recommends using let or const Instead, they create a new scope per iteration.
The magic wasn’t in closures. The magic was in understanding that JavaScript remembers where functions come from.
Where Closures Actually Matter
Here’s the dirty secret: you’re already using closures. You just didn’t know you were naming them.
Callbacks: Every event listener, every .then(), every callback function is a closure. It remembers the scope it was defined in, even when it runs way later.
Factories and Constructors: That counter example above? That’s a factory. It returns new objects with built-in memory. React Hooks do this, useState gives you a closure that remembers your component’s state.
Module Pattern: Before ES modules existed, devs used closures to create private variables:
javascript
const userModule = (function() {
let privateData = ‘secret’;
return {
getData() { return privateData; },
setData(val) { privateData = val; }
};
})();Only getData and setData can touch privateData. It’s private because it’s locked inside a closure.
Debouncing and Throttling: Every time you debounce a search input, you’re using a closure to remember state between function calls.
The Takeaway
Closures aren’t some advanced, optional concept. They’re foundational to how JavaScript works.
The moment you stop thinking of them as “a closure” and start thinking of them as “a function with memory,” everything clicks.
Test this yourself: take code you’ve written. Find a function inside another function. There’s your closure, doing its job, remembering its scope, silently making your code work.
Once you see them, you can’t unsee them. And that’s when you level up.
Level Up Your Skills (and Your Portfolio)
If you want to actually understand closures, not just read about them, I’ve built learning packs that force you to think like a developer:
💻 HTML to Hero: Build 10 Real Web Projects ($4+)
10 beginner-friendly HTML & CSS projects
1 bonus mobile “Link-in-Bio” site
Progress tracker + dev cheatsheet
Organized Notion workspace
Get it here: https://devforgehq.gumroad.com/l/hyhjt
⚡ JavaScript Launchpad: Build 15 Real Interactive Projects ($8+)
15 projects from DOM basics to API-powered apps (closures included!)
Skill & project tracker
Cheatsheets + portfolio export guide
Fully organized in Notion
Get it here: https://devforgehq.gumroad.com/l/tijggh
No theory dumps. No fluff. Just builds that force you to think like a dev.
Until next week,
— DevForge
P.S. Hit reply: What JavaScript concept finally clicked for you? I’m curious what broke your brain before suddenly making sense. I read every response.


