What they're testing
Whether you understand closures as a mechanism you use deliberately, or as a term from a book.
The short answer~30 seconds
A closure is a function plus the lexical environment it was DEFINED in — so it can still read the enclosing function's variables long after that function returned. The three things I use them for most: keeping private state without a class, producing pre-configured functions like debounce/throttle, and holding context inside callbacks.
The long answer
The common misreading: a closure captures the BINDING by reference, not a snapshot of the value. That's why a var loop logs the final value everywhere — three closures share one binding. It's also why a closure can mutate the outer variable, which is what makes counters and memo caches possible.
The under-discussed flip side is memory. As long as a closure lives, the environment it references lives too — including variables it never reads, depending on the engine. A DOM listener whose closure points at a large array keeps that array alive after the component unmounted, and that's the most common SPA leak there is. Removing listeners on cleanup isn't ceremony.
Three real uses
// 1. Trạng thái riêng tư — không ai chạm được vào `count` từ bên ngoài
function makeCounter() {
let count = 0;
return { inc: () => ++count, get: () => count };
}
// 2. Hàm cấu hình sẵn
const debounce = (fn, ms) => {
let timer; // <- sống giữa các lần gọi
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), ms);
};
};
// 3. Rò rỉ: closure giữ `rows` sống mãi cùng listener
const rows = await fetchHugeTable();
window.addEventListener('resize', () => layout(rows));
// -> phải removeEventListener, nếu không `rows` không bao giờ được thu hồiWhat they'll ask next
?How do closures and scope differ?
Scope is the compile-time lookup rule; a closure is the runtime consequence — the function carries the scope it was born in. Put differently, scope is the law and the closure is what remains after the enclosing call has finished.
?What closure bug shows up in React?
The stale closure: a callback inside useEffect captures the state from the render that created it, so with an incomplete dependency array it keeps reading the old value forever. The fix is complete dependencies, or the functional update form setX(prev => …) so you never need to read the current value.
These lose points
- Reciting the textbook definition and stopping. The "what have you used it for" half is asked deliberately.
- Not knowing closures retain memory. It's the near-certain follow-up in a mid-level round.