Closure
Closure = inner function remembers outer scope
What is a Closure?
"Function + its lexical environment"
A closure is when an inner function has access to variables from its outer (enclosing) scope, even after the outer function has returned.
How Closures Work
Inner function captures outer variables
function outer() {
let count = 0;
function inner() {
count++;
console.log(count);
}
return inner;
}
const counter = outer();
counter(); // 1
counter(); // 2
"The inner function maintains a reference to the outer function's variables, creating a closure."
Common Use Cases
Data privacy · Callbacks · Currying
- Data privacy: Private variables
- Callbacks: Event handlers, async operations
- Currying: Partial function application
- Module pattern: Encapsulation
"Closures enable data privacy, callback functions, currying, and the module pattern."
Data Privacy Example
Private variables with closures
function createCounter() {
let count = 0; // private
return {
increment: () => ++count,
decrement: () => --count,
getCount: () => count,
};
}
const counter = createCounter();
counter.increment(); // count is private
"Closures create private variables that can't be accessed directly from outside."
Loop and Closure Gotcha
Loop variable captured by reference
❌ Problem:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Prints: 3, 3, 3
✅ Solution:
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Prints: 0, 1, 2
Or with IIFE:
for (var i = 0; i < 3; i++) {
(function (j) {
setTimeout(() => console.log(j), 100);
})(i);
}
"In loops, use let instead of var, or IIFE to create a new scope for each iteration."
Memory Considerations
Closures keep references alive
- Closures keep outer variables in memory
- Can cause memory leaks if not careful
- Unused closures should be released
"Closures maintain references to outer variables, which can impact memory if not managed properly."
Module Pattern
Closures enable modules
const Module = (function () {
let private = "hidden";
return {
public: "visible",
getPrivate: () => private,
setPrivate: (val) => {
private = val;
},
};
})();
"The module pattern uses closures to create private and public members."
"A closure is a function that retains access to variables from its outer lexical scope even after the outer function has returned. This enables data privacy, callback functions, and the module pattern. Common gotchas include loop variable capture, which is solved by using let or IIFE. Closures keep references alive, so memory management is important."
🧠 Ultra-Short Cheat Sheet
Inner function + outer scope
Data privacy
Callbacks
Currying
Module pattern
Loop gotcha (use let)
Memory considerations