Syntax
function outer() {
let value = 0;
return function inner() { return value; };
}Examples
Basic Closure
An inner function retaining access to its outer function's variable.
function makeCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3 - count persists between callsPrivate State with Closures
Using a closure to create genuinely private variables before class private fields existed.
function createBankAccount(initialBalance) {
let balance = initialBalance; // not accessible from outside
return {
deposit(amount) {
balance += amount;
return balance;
},
withdraw(amount) {
if (amount > balance) {
console.log("Insufficient funds");
return balance;
}
balance -= amount;
return balance;
},
getBalance() {
return balance;
}
};
}
const account = createBankAccount(100);
console.log(account.deposit(50)); // 150
console.log(account.withdraw(30)); // 120
// balance itself cannot be accessed or modified directly from outsideFunction Factories
Using closures to generate specialized functions.
function multiplyBy(factor) {
return function(number) {
return number * factor;
};
}
const double = multiplyBy(2);
const triple = multiplyBy(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15Best practices
- Use closures to create private state that cannot be accessed or mutated from outside a function
- Be aware that closures keep their referenced variables alive in memory - avoid creating unnecessary closures in hot code paths or long-lived loops
- Use closures for function factories and configurable, reusable function generators
- Remember that each call to an outer function creates a new, independent closure - they do not share state with each other
Runtime & versions
Browsers and JavaScript runtimes. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
ECMAScript specification