Closures & Lexical Scope
If you're asked about closures in a senior interview and you give a textbook definition, you've already lost. Senior engineers explain closures through real-world implications.
What is a Closure?
A closure is a function that retains access to its lexical scope even when executed outside that scope.
function createCounter() {
let count = 0;
return {
increment: () => ++count,
getCount: () => count,
};
}
const counter = createCounter();
counter.increment();
counter.increment();
counter.getCount(); // 2count is not accessible from outside, but the returned functions close over it. This is encapsulation without classes.
Why Closures Matter in React
Every React hook relies on closures:
function Counter() {
const [count, setCount] = useState(0);
// This callback closes over `count`
const handleClick = () => {
console.log(count); // Always the value from this render
};
return <button onClick={handleClick}>{count}</button>;
}The Stale Closure Problem
This is the #1 closure-related bug in React:
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setCount(count + 1); // Bug: `count` is always 0
}, 1000);
return () => clearInterval(id);
}, []); // Empty deps = closure captures initial `count`
}Fix: Use the functional updater form:
setCount(prev => prev + 1);This avoids the stale closure entirely because you're not reading count â you're telling React to compute the next value from the previous one.
Senior-Level Pattern: Closures for Encapsulation
function createAPI(baseURL) {
const token = getStoredToken();
return {
get: (path) => fetch(`${baseURL}${path}`, {
headers: { Authorization: `Bearer ${token}` },
}),
post: (path, data) => fetch(`${baseURL}${path}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
}),
};
}The token and baseURL are private. No class needed, no this binding issues.
Interview Signal
When interviewers ask about closures, they want to see:
- Practical understanding â not just "a function that remembers its scope"
- Awareness of pitfalls â stale closures, memory leaks
- Architectural application â module patterns, factory functions, hook internals