MediumClosures & Scope🐛 Debug Challenge

Counter factory shares global state

Buggy Code — Can you spot the issue?

let count = 0;

function makeCounter() {
  return {
    increment() { count++; },
    value()     { return count; },
  };
}

const a = makeCounter();
const b = makeCounter();
a.increment();
a.increment();
b.increment();
console.log(a.value());
console.log(b.value());

Fixed Code

function makeCounter() {
  let count = 0;
  return {
    increment() { count++; },
    value()     { return count; },
  };
}

const a = makeCounter();
const b = makeCounter();
a.increment();
a.increment();
b.increment();
console.log(a.value());
console.log(b.value());

Bug Explained

Bug: count is declared outside makeCounter — all counters share the same variable. a and b are not independent.

Explanation: Moving count inside makeCounter creates a new independent variable per call via closure.

Key Insight: For factory functions, declare state inside the factory — each call gets its own private closure.

More Closures & Scope Debug Challenges

Easyvar in loop — all closures share one variableMediumShared memoize cache across all functionsEasyWallet exposes stale primitive snapshotHardDefault parameter creates new function every call

Practice spotting bugs live →

38 debug challenges with AI hints

🐛 Try Debug Lab