You've been using closures without knowing it. Time to understand what's really happening."
📋 Table of Contents
What is a Closure?
Why Should You Care?
Real-World Examples
Common Mistakes to Avoid
Advanced Use Cases
Summary
What is a Closure?
Imagine you have a backpack 🎒. You put your books inside it. Even after you leave school, the backpack remembers the books that were inside it.
That's exactly what a closure is in JavaScript.
A closure is a function that remembers the variables from its outer scope, even after that outer scope has finished executing.function makeCounter() {
let count = 0;
return function () {
count++;
console.log(count);
};
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
counter(); // 3
makeCounter() already finished running — yet count is still alive. That is a closure.
Why Should You Care?
Closures are everywhere in JavaScript:
✅ Event listeners
✅ setTimeout / setInterval
✅ React hooks (useState uses closures!)
✅ Data privacy & module patterns
Real-World Examples
1️⃣ Data Privacy
function createBankAccount(initialBalance) {
let balance = initialBalance; // Private!
return {
deposit(amount) {
balance += amount;
console.log(Deposited ${amount}. Balance: ${balance});
},
withdraw(amount) {
if (amount > balance) { console.log("Insufficient funds!"); return; }
balance -= amount;
console.log(Withdrew ${amount}. Balance: ${balance});
},
getBalance() { return balance; }
};
}
const myAccount = createBankAccount(1000);
myAccount.deposit(500); // Balance: 1500
console.log(myAccount.balance); // undefined ← hidden!
3️⃣ The Classic Loop Bug 🐛
// ❌ Broken — prints 3, 3, 3
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// ✅ Fixed — prints 0, 1, 2
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
Common Mistakes to Avoid
⚠️ Memory Leaks
// ❌ hugeArray stays in memory forever
function attach() {
const hugeArray = new Array(100000).fill("data");
document.getElementById("btn").addEventListener("click", () => {
console.log(hugeArray.length);
});
}
// ✅ Only close over what you need
function attach() {
const length = new Array(100000).fill("data").length;
document.getElementById("btn").addEventListener("click", () => {
console.log(length);
});
}
Advanced Use Cases
🔥 Memoization
function memoize(fn) {
const cache = {};
return function (...args) {
const key = JSON.stringify(args);
if (cache[key]) { console.log("From cache ⚡"); return cache[key]; }
cache[key] = fn(...args);
return cache[key];
};
}
const fastSquare = memoize((n) => n * n);
fastSquare(10); // Computed
fastSquare(10); // From cache ⚡
Summary
Concept
What It Means
Closure
Function that remembers its outer scope
Data Privacy
Hide variables using closures
Function Factory
Create specialized functions dynamically
Memoization
Cache results using closures
Loop Bug
Use let instead of var
🎯 Quick Challenge
What does this print and why?
function outer() {
let x = 10;
function inner() {
let x = 20;
console.log(x);
}
inner();
console.log(x);
}
outer();
Drop your answer in the comments! 👇
Follow me for Part 2: Prototypes & Prototype Chain 🔗
Top comments (0)