
"How do closures work in JavaScript? Explain lexical scoping, what a closure captures, and describe a few places you have used closures in mobile code such as event handlers, debouncing, or async callbacks."
JavaScript determines variable visibility based on where functions are defined, not where they are called. An inner function can access variables from its own scope and from the outer scopes surrounding its definition.
function outer() {
const x = 10;
function inner() {
return x;
}
return inner;
}
A closure is a function bundled with references to the variables in its lexical environment. Even after the outer function returns, the inner function can still read or modify those captured variables.
function makeCounter() {
let count = 0;
return function () {
count += 1;
return count;
};
}
Closures are commonly used to keep state private without exposing it globally. This is useful for counters, memoized helpers, throttled handlers, and one-off configuration wrappers in mobile UI code.
function createTracker(screenName) {
return function track(eventName) {
console.log(screenName, eventName);
};
}
Callbacks for timers, promises, gestures, and button presses often rely on closures to retain surrounding values. This lets the callback remember IDs, flags, or configuration values when it runs later.
function fetchWithRetry(url, retries) {
return function attempt() {
return fetch(url).catch(() => {
if (retries-- > 0) return attempt();
throw new Error('failed');
});
};
}
Closures can accidentally capture stale values, especially in UI frameworks with re-renders, or retain large objects longer than needed. Interview answers are stronger when they mention both usefulness and memory/lifecycle tradeoffs.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // logs 3, 3, 3
}