EasyClosures & Scope🐛 Debug Challenge

Wallet exposes stale primitive snapshot

Buggy Code — Can you spot the issue?

function createWallet(initial) {
  let _balance = initial;
  return {
    _balance,
    deposit(n)   { _balance += n; },
    getBalance() { return _balance; },
  };
}

const w = createWallet(100);
w.deposit(50);
console.log(w._balance);
console.log(w.getBalance());

Fixed Code

function createWallet(initial) {
  let _balance = initial;
  return {
    deposit(n)   { _balance += n; },
    getBalance() { return _balance; },
  };
}

const w = createWallet(100);
w.deposit(50);
console.log(w._balance);
console.log(w.getBalance());

Bug Explained

Bug: return { _balance } copies the primitive value (100) at creation time. It does not create a live reference. Deposits update the closure variable but not the snapshot in the object.

Explanation: Removing _balance from the returned object makes it truly private. The only way to read it is getBalance(), which always reads the live closure variable.

Key Insight: Returning a primitive copies its value. Expose only methods that close over the variable — that is true encapsulation.

More Closures & Scope Debug Challenges

Easyvar in loop — all closures share one variableMediumCounter factory shares global stateMediumShared memoize cache across all functionsHardDefault parameter creates new function every call

Practice spotting bugs live →

38 debug challenges with AI hints

🐛 Try Debug Lab