What is a closure?
A closure happens when a function “remembers” the variables from the scope where it was created, even after that scope has finished running.
In other words:
👉 A function carries around a backpack of variables from the place it was born.
1. Simple example
function outer() {
const message = "Hello from outer!";
function inner() {
console.log(message); // uses variable from outer scope
}
return inner;
}
const fn = outer();
fn(); // "Hello from outer!"
-
inner
is returned out ofouter
. - Even though
outer
has finished,inner
still has access tomessage
. - That’s the closure —
inner
“closes over” themessage
variable.
2. Closure with parameters
function makeMultiplier(multiplier) {
return function (x) {
return x * multiplier;
};
}
const double = makeMultiplier(2);
console.log(double(5)); // 10
const triple = makeMultiplier(3);
console.log(triple(5)); // 15
-
double
remembersmultiplier = 2
. -
triple
remembersmultiplier = 3
. - Each returned function has its own closure environment.
3. In React hooks
Closures explain why we can do this:
const greeting = useMemo(() => {
return `Hello, ${name}`;
}, [name]);
- The
() => { ... }
factory closes over the current value ofname
. - React doesn’t pass
name
into the function — the closure makes it available. - That’s why we must put
name
in the dependency array, so React knows when the closed-over value might change.
4. Analogy 🎒
Imagine a function is a traveler.
- When it’s created, it packs a backpack with the variables in scope.
- Later, no matter where it goes, it can unzip the backpack and use those variables.
Java vs JavaScript analogy
Java local variables
In Java:
void outer() {
String message = "Hello";
class Inner {
void print() {
System.out.println(message);
}
}
Inner i = new Inner();
i.print(); // prints "Hello"
}
-
message
is a local variable ofouter()
. - Inner classes in Java can “capture” these variables, but Java enforces them to be effectively final (not reassigned after creation). So inner classes in Java have a limited version of closure.
JavaScript closures
In JS:
function outer() {
let message = "Hello";
function inner() {
console.log(message);
}
return inner;
}
const fn = outer();
fn(); // "Hello"
-
message
is a local variable ofouter()
. -
inner
keeps a live reference tomessage
even afterouter
has finished. - Unlike Java, JavaScript allows closures over variables that can change:
function outer() {
let count = 0;
return function() {
count++;
return count;
};
}
const inc = outer();
console.log(inc()); // 1
console.log(inc()); // 2
console.log(inc()); // 3
Here count
behaves like private state — accessible only through the closure.
Key difference
- Java local variables (in lambdas/inner classes) → captured by value, must be effectively final.
- JavaScript closures → captured by reference, can update over time, and the function “remembers” the variable for as long as it’s alive.
Analogy
- In Java: closure = you take a snapshot of a local variable at the time the inner class/lambda was created.
- In JS: closure = you keep a live wire to the variable itself — if it changes later, your function sees the updated value.
✅ So closure variables look like local variables in Java, but in JavaScript they are kept alive and mutable by the function that closes over them.
Top comments (0)