A closure is created when a function remembers and accesses variables from its outer scope, even after that outer function has finished executing.
In short: “A function inside another function that can still access its parent’s variables.”
✨ Basic Example:
function outer() {
let count = 0;
return function inner() {
count++;
console.log(count);
};
}
const counter = outer();
counter(); // 1
counter(); // 2
counter(); // 3
👉 Even though outer has finished executing, inner still has access to count — that’s a closure.
📌 Real Use Cases of Closures:
1. Private Variables (Data Encapsulation)
Closures help create variables that can’t be directly accessed from outside.
function createBankAccount() {
let balance = 0;
return {
deposit(amount) {
balance += amount;
console.log(`Balance: ₹${balance}`);
},
getBalance() {
return balance;
}
};
}
const account = createBankAccount();
account.deposit(1000); // Balance: ₹1000
console.log(account.getBalance()); // 1000
// console.log(account.balance); ❌ undefined (private)
2. Event Handlers / Callbacks
Closures let event listeners remember the context in which they were created.
function setupButton() {
let clicks = 0;
document.getElementById('btn').addEventListener('click', () => {
clicks++;
console.log(`Clicked ${clicks} times`);
});
}
setupButton();
👉 The click handler remembers clicks even after setupButton is done.
3. Memoization / Caching
Closures can store previously computed results to improve performance.
function memoizedAdd() {
const cache = {};
return function(num) {
if (cache[num]) return cache[num];
console.log('Calculating...');
cache[num] = num + 10;
return cache[num];
};
}
const add = memoizedAdd();
console.log(add(5)); // Calculating... 15
console.log(add(5)); // 15 (from cache)
✅ In simple words: Closures let a function “remember” variables even after the outer function is gone, making them powerful for private state, caching, and event handling.