Difficulty: Intermediate
What is a closure in JavaScript? Explain with examples and real-world use cases.
A closure is a function that remembers and has access to variables from its outer (enclosing) function's scope, even after the outer function has returned. Closures are created every time a function is created.
Key points: 1. A closure gives you access to an outer function's scope from an inner function. 2. Closures are commonly used for data privacy, function factories, and partial application. 3. Variables in a closure are references (not copies), so they reflect the latest value.
function outer() {
let count = 0;
return function inner() {
count++;
return count;
};
}
const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
inner() forms a closure over 'count'. Even after outer() returns, inner() still has access to count.
function createBankAccount(initialBalance) {
let balance = initialBalance;
return {
deposit(amount) {
balance += amount;
return `Deposited ${amount}. Balance: ${balance}`;
},
withdraw(amount) {
if (amount > balance) return 'Insufficient funds';
balance -= amount;
return `Withdrew ${amount}. Balance: ${balance}`;
},
getBalance() {
return balance;
}
};
}
const account = createBankAccount(100);
console.log(account.deposit(50));
console.log(account.withdraw(30));
console.log(account.getBalance());
balance is private - it can only be accessed through the returned methods. This is the module pattern.
// Problem: all callbacks log 3
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log('var:', i), 100);
}
// Fix 1: use let (block scoping)
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log('let:', j), 200);
}
// Fix 2: use IIFE closure
for (var k = 0; k < 3; k++) {
(function(k) {
setTimeout(() => console.log('iife:', k), 300);
})(k);
}
var is function-scoped, so all callbacks share the same i. let creates a new binding per iteration. IIFE captures each value.
Closures, Lexical Scope, Data Privacy, Function Factory