Clean • Professional
A closure in JavaScript is one of the most powerful and important concepts in the language. A closure happens when a function “remembers” the variables from its outer scope, even after that outer function has finished executing.
Closures make it possible to preserve state, create private variables, and build modular, maintainable code.
When a function is created inside another function, the inner function forms a scope chain that includes:
Even if the outer function finishes execution, the inner function still “remembers” the environment in which it was created.
That preserved environment is what we call a closure.
Basic Example of a Closure
function outerFunction() {
let count = 0; // variable in outer scope
function innerFunction() {
count++;
console.log(`Current count: ${count}`);
}
return innerFunction;
}
const counter = outerFunction();
counter(); // Output: Current count: 1
counter(); // Output: Current count: 2
counter(); // Output: Current count: 3
Closures are often used to create private data — variables that can’t be accessed directly from outside a function.
function createBankAccount(initialBalance) {
let balance = initialBalance; // private variable
return {
deposit(amount) {
balance += amount;
console.log(`Deposited: ${amount}, New Balance: ${balance}`);
},
withdraw(amount) {
if (amount <= balance) {
balance -= amount;
console.log(`Withdrew: ${amount}, New Balance: ${balance}`);
} else {
console.log("Insufficient funds!");
}
},
getBalance() {
return balance;
}
};
}
const myAccount = createBankAccount(1000);
myAccount.deposit(500);
myAccount.withdraw(300);
console.log(myAccount.getBalance()); // Output: 1200
A common place where developers encounter closures is inside loops.
Example Problem:
for (var i = 1; i <= 3; i++) {
setTimeout(() => console.log(i), 1000);
}
Solution using Closure or let:
for (let i = 1; i <= 3; i++) {
setTimeout(() => console.log(i), 1000);
}
OR using a closure:
for (var i = 1; i <= 3; i++) {
((num) => {
setTimeout(() => console.log(num), 1000);
})(i);
}
| Use Case | Description | Example |
|---|---|---|
| Data Privacy | Hide variables from global scope | Private counters, stateful components |
| Event Handlers | Remember values when events trigger later | Button click handlers |
| Functional Programming | Create functions with pre-configured data | makeAdder(5) returning a function that adds 5 |
| State Management | Preserve state without global variables | Counters, score tracking, timers |
Example: Function Factory Using Closures
function makeAdder(x) {
return function(y) {
return x + y;
};
}
const add5 = makeAdder(5);
const add10 = makeAdder(10);
console.log(add5(2)); // Output: 7
console.log(add10(2)); // Output: 12Â