JavaScript closures and scope quiz (10 questions)
June 6, 2026
- JavaScript
- Closures
- Frontend
Closures and scope are where JavaScript interviews start shifting from surface syntax to runtime reasoning. The candidate usually is not being tested on vocabulary alone, but on whether they can predict what code actually sees and when.
If this set exposed weak spots, pair it with async questions next. A lot of real interview bugs happen when closures, timers, and promises all interact in the same snippet.
Question 1
What is a closure in JavaScript?
Reveal answer
Answer
A function bundled with access to variables from its lexical outer scope - A closure is a function that keeps access to variables from its lexical outer scope even after that outer function has returned.
Explanation
Closures are a normal part of how JavaScript functions work. They power callbacks, factory functions, memoization, and many module-like patterns.
Common interview notes
Strong answers use a short real example, such as a function returning another function that increments a private counter.
Question 2
In JavaScript, what does lexical scope mean?
Reveal answer
Answer
Variable access depends on where the function is defined in the source code - Lexical scope means variable access is determined by where a function is defined, not where it is called.
Explanation
JavaScript resolves identifiers by looking outward through the scope chain created by the source structure. This is why moving a function definition can change what variables it can see.
Common interview notes
A common follow-up is to compare lexical scope with dynamic scope and explain that JavaScript uses lexical scope.
Question 3
Which declaration is block-scoped?
Reveal answer
Answer
let - let is block-scoped.
Explanation
Variables declared with let and const exist only inside the nearest block. var is function-scoped, which is why it behaves differently inside loops and conditionals.
Example
if (true) {
let count = 1;
}
// count is not defined here Common interview notes
Interviewers often ask you to compare let and var inside a for loop with asynchronous callbacks.
Question 4
Why does this classic loop produce repeated values with var and setTimeout?
Reveal answer
Answer
var creates one shared function-scoped binding that each callback closes over - With var, each callback closes over the same function-scoped binding, so they all read the final loop value later.
Explanation
The issue is not the timer itself but the shared binding created by var. Using let in the loop creates a fresh block-scoped binding for each iteration.
Example
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// logs 3, 3, 3 Common interview notes
A strong follow-up answer explains both the let fix and the IIFE fix for older code.
Question 5
What is hoisting best described as?
Reveal answer
Answer
The language's creation of bindings before execution, with different initialization behavior by declaration type - Hoisting is the creation of bindings before execution, with different behavior depending on whether you used var, let, const, or function declarations.
Explanation
Function declarations are available earlier in their scope, var is hoisted and initialized to undefined, and let or const exist in the temporal dead zone until their declaration is evaluated. Interviews usually care about this behavior, not the metaphor alone.
Common interview notes
Good answers mention that hoisting does not mean let and const are safely usable before their declaration line.
Question 6
What happens if you read a let variable before its declaration in the same scope?
Reveal answer
Answer
It throws a ReferenceError - Reading a let variable before its declaration throws a ReferenceError.
Explanation
That behavior comes from the temporal dead zone, the period between entering the scope and executing the declaration. const behaves the same way with respect to early access.
Common interview notes
This question often checks whether the candidate incorrectly generalizes var behavior to let and const.
Question 7
Which pattern is a practical use of closures?
Reveal answer
Answer
Hiding private state inside a factory function - Closures are often used to hide private state inside a factory function.
Explanation
A returned function can still access variables from the outer function even after that outer function finishes. This is a simple way to encapsulate state without exposing it directly on an object.
Example
function createCounter() {
let count = 0;
return () => ++count;
} Common interview notes
A useful follow-up is when a class or module would be clearer than closure-based private state.
Question 8
Inside a nested function, JavaScript looks up a missing variable name by searching where first?
Reveal answer
Answer
The current scope, then outer lexical scopes outward - JavaScript looks in the current scope first, then walks outward through outer lexical scopes.
Explanation
This chain of nested scopes is what allows inner functions to use variables defined outside them. If the name is not found anywhere in the scope chain, a ReferenceError occurs when the code runs.
Common interview notes
Strong answers distinguish the lexical scope chain from object prototype lookup, which is a different mechanism.
Question 9
Which statement about closures and memory is most accurate?
Reveal answer
Answer
Closures can keep referenced outer variables alive as long as the inner function remains reachable - Closures can keep referenced outer variables alive while the closure is still reachable.
Explanation
This is not a problem by itself, but it matters when long-lived callbacks retain large objects or DOM references unnecessarily. Interviews sometimes use this question to bridge into performance or leak debugging.
Common interview notes
A good follow-up is to describe one real case, such as an event handler retaining stale component data.
Question 10
Why is let usually preferred over var in modern interview answers?
Reveal answer
Answer
let avoids accidental function-scoped sharing and is easier to reason about - let is usually preferred because block scope matches developer expectations better and avoids many var-related footguns.
Explanation
let reduces bugs caused by unintended sharing across loops and blocks, especially with asynchronous callbacks. It also makes code easier to explain during interviews because the scoping model is more predictable.
Common interview notes
A strong answer mentions const as the default for bindings that should not be reassigned, with let reserved for actual rebinding.
Full answer key
Review every answer in one place, with explanations and interview tips below.
1. What is a closure in JavaScript?
Answer summary
A function bundled with access to variables from its lexical outer scope — A closure is a function that keeps access to variables from its lexical outer scope even after that outer function has returned.
Closures are a normal part of how JavaScript functions work. They power callbacks, factory functions, memoization, and many module-like patterns.
Interview tip: Strong answers use a short real example, such as a function returning another function that increments a private counter.
2. In JavaScript, what does lexical scope mean?
Answer summary
Variable access depends on where the function is defined in the source code — Lexical scope means variable access is determined by where a function is defined, not where it is called.
JavaScript resolves identifiers by looking outward through the scope chain created by the source structure. This is why moving a function definition can change what variables it can see.
Interview tip: A common follow-up is to compare lexical scope with dynamic scope and explain that JavaScript uses lexical scope.
3. Which declaration is block-scoped?
Answer summary
let — let is block-scoped.
Variables declared with let and const exist only inside the nearest block. var is function-scoped, which is why it behaves differently inside loops and conditionals.
if (true) {
let count = 1;
}
// count is not defined here Interview tip: Interviewers often ask you to compare let and var inside a for loop with asynchronous callbacks.
4. Why does this classic loop produce repeated values with var and setTimeout?
Answer summary
var creates one shared function-scoped binding that each callback closes over — With var, each callback closes over the same function-scoped binding, so they all read the final loop value later.
The issue is not the timer itself but the shared binding created by var. Using let in the loop creates a fresh block-scoped binding for each iteration.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// logs 3, 3, 3 Interview tip: A strong follow-up answer explains both the let fix and the IIFE fix for older code.
5. What is hoisting best described as?
Answer summary
The language's creation of bindings before execution, with different initialization behavior by declaration type — Hoisting is the creation of bindings before execution, with different behavior depending on whether you used var, let, const, or function declarations.
Function declarations are available earlier in their scope, var is hoisted and initialized to undefined, and let or const exist in the temporal dead zone until their declaration is evaluated. Interviews usually care about this behavior, not the metaphor alone.
Interview tip: Good answers mention that hoisting does not mean let and const are safely usable before their declaration line.
6. What happens if you read a let variable before its declaration in the same scope?
Answer summary
It throws a ReferenceError — Reading a let variable before its declaration throws a ReferenceError.
That behavior comes from the temporal dead zone, the period between entering the scope and executing the declaration. const behaves the same way with respect to early access.
Interview tip: This question often checks whether the candidate incorrectly generalizes var behavior to let and const.
7. Which pattern is a practical use of closures?
Answer summary
Hiding private state inside a factory function — Closures are often used to hide private state inside a factory function.
A returned function can still access variables from the outer function even after that outer function finishes. This is a simple way to encapsulate state without exposing it directly on an object.
function createCounter() {
let count = 0;
return () => ++count;
} Interview tip: A useful follow-up is when a class or module would be clearer than closure-based private state.
8. Inside a nested function, JavaScript looks up a missing variable name by searching where first?
Answer summary
The current scope, then outer lexical scopes outward — JavaScript looks in the current scope first, then walks outward through outer lexical scopes.
This chain of nested scopes is what allows inner functions to use variables defined outside them. If the name is not found anywhere in the scope chain, a ReferenceError occurs when the code runs.
Interview tip: Strong answers distinguish the lexical scope chain from object prototype lookup, which is a different mechanism.
9. Which statement about closures and memory is most accurate?
Answer summary
Closures can keep referenced outer variables alive as long as the inner function remains reachable — Closures can keep referenced outer variables alive while the closure is still reachable.
This is not a problem by itself, but it matters when long-lived callbacks retain large objects or DOM references unnecessarily. Interviews sometimes use this question to bridge into performance or leak debugging.
Interview tip: A good follow-up is to describe one real case, such as an event handler retaining stale component data.
10. Why is let usually preferred over var in modern interview answers?
Answer summary
let avoids accidental function-scoped sharing and is easier to reason about — let is usually preferred because block scope matches developer expectations better and avoids many var-related footguns.
let reduces bugs caused by unintended sharing across loops and blocks, especially with asynchronous callbacks. It also makes code easier to explain during interviews because the scoping model is more predictable.
Interview tip: A strong answer mentions const as the default for bindings that should not be reassigned, with let reserved for actual rebinding.
Try each question on your own, then open "Reveal answer" for the full write-up. For tailored practice and Check feedback on open-ended responses, use PrepAhead in the app - not on blog pages.