A closure is a feature of JavaScript where an inner function has access to the variables and parameters of its outer function, even after the outer function has finished executing. Closures are essential for maintaining private state, creating function factories, and asynchronous programming.
When a function is declared inside another function, the inner function forms a closure. This means it "remembers" the environment in which it was created.
function makeCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
count variable even after makeCounter() has finished.counter to have its own private count state.
const anotherCounter = makeCounter();
anotherCounter(); // 1 (separate count!)
Closures enable data privacy by keeping variables hidden from the outside world.
function secretHolder(secret) {
return {
getSecret: function() { return secret; },
setSecret: function(val) { secret = val; }
};
}
const holder = secretHolder("hidden");
holder.getSecret(); // "hidden"
holder.setSecret("new secret");
holder.getSecret(); // "new secret"
Be careful with closures inside loops! Each closure captures the variable, not its value at the time.
var funcs = [];
for (var i = 0; i < 3; i++) {
funcs.push(function() { return i; });
}
funcs[0](); // 3, not 0!
let in ES6, or an IIFE to capture values correctly.
let funcs = [];
for (let i = 0; i < 3; i++) {
funcs.push(function() { return i; });
}
funcs[0](); // 0