This post is a deep-dive explanation of a JavaScript quiz originally shared as a LinkedIn post.
If you voted on the poll and were unsure about the answer, let’s break it down properly.
🧠 The LinkedIn Question
What will be the output?
function createCounter() {
let count = 0;
return {
increment() {
count++;
},
getCount() {
return count;
},
reset() {
let count = 0;
}
};
}
const counter = createCounter();
counter.increment();
counter.increment();
counter.reset();
console.log(counter.getCount());
💡 Hint: Think about which count the closure actually captures
✅ Solution
Correct Output:
2
This result surprises many developers, even those familiar with closures.
To understand why this happens, we need to understand how closures work and how variable shadowing behaves with let.
🔍 Understanding Closures (Quick Recap)
A closure is created when a function:
- Is defined inside another function
- Uses variables from its outer function
- Continues to access those variables after the outer function has finished executing
In JavaScript, closures capture variables, not values.
🧩 Line-by-Line Explanation
1. Creating the closed-over variable
function createCounter() {
let count = 0;
-
countis a local variable - It belongs to the execution context of
createCounter - This is the variable that will be captured by the closure
2. Returning functions that reference count
return {
increment() {
count++;
},
getCount() {
return count;
},
- Both functions reference the same
count - They do not create copies
- This shared reference is the closure
3. The subtle bug in reset
reset() {
let count = 0;
}
This line causes the confusion.
-
let count = 0creates a new block-scoped variable - It shadows the outer
count - The original closed-over
countremains unchanged
Once reset() finishes, this inner count is discarded.
4. Executing the logic
const counter = createCounter();
-
createCounter()runs once - One
countvariable is created and shared
counter.increment();
counter.increment();
-
countbecomes2
counter.reset();
- A new
countis created and destroyed - The closure’s
countis untouched
5. Reading the final value
console.log(counter.getCount());
- Reads the closed-over
count - Output is
2
🧠 Why This Matters
This pattern shows up frequently in:
- React hooks
- Stateful utilities
- Event handlers
- Encapsulated business logic
Misunderstanding closures can lead to silent state bugs that are hard to trace.
✅ Correct reset Implementation
If the intention was to reset the counter, it should be:
reset() {
count = 0;
}
This updates the same variable captured by the closure.
🎯 Key Takeaways
- Closures capture variables, not scopes or values
-
letintroduces block scope and allows shadowing - Shadowing does not mutate the closed-over variable
- Always check which variable your function is modifying
Follow me for JavaScript puzzles and weekly curations of developer talks & insights at Talk::Overflow: https://talkoverflow.substack.com/
Top comments (0)