DEV Community

ValPetal Tech Labs
ValPetal Tech Labs

Posted on

JavaScript Quiz

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());
Enter fullscreen mode Exit fullscreen mode

💡 Hint: Think about which count the closure actually captures


✅ Solution

Correct Output:

2
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode
  • count is 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;
  },
Enter fullscreen mode Exit fullscreen mode
  • 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;
}
Enter fullscreen mode Exit fullscreen mode

This line causes the confusion.

  • let count = 0 creates a new block-scoped variable
  • It shadows the outer count
  • The original closed-over count remains unchanged

Once reset() finishes, this inner count is discarded.


4. Executing the logic

const counter = createCounter();
Enter fullscreen mode Exit fullscreen mode
  • createCounter() runs once
  • One count variable is created and shared
counter.increment();
counter.increment();
Enter fullscreen mode Exit fullscreen mode
  • count becomes 2
counter.reset();
Enter fullscreen mode Exit fullscreen mode
  • A new count is created and destroyed
  • The closure’s count is untouched

5. Reading the final value

console.log(counter.getCount());
Enter fullscreen mode Exit fullscreen mode
  • 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;
}
Enter fullscreen mode Exit fullscreen mode

This updates the same variable captured by the closure.


🎯 Key Takeaways

  • Closures capture variables, not scopes or values
  • let introduces 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)