AniUI Academy

Build a counter with private state

easyFunctions & Closures+150 XPPractice

Before hooks, this was how every widget kept state: a factory function returns an object of methods, and the count itself lives in the factory's scope where no caller can reach it. It is still how you write a module that must not be poked at from the console.

Implement createCounter(start = 0). It returns an object with exactly four methods: increment() adds one and returns the new count, decrement() subtracts one and returns the new count, value() returns the current count without changing it, and reset() sets the count back to start and returns it. The count must not be exposed as a property on the returned object, so its only own enumerable properties are those four methods. Two counters created separately share nothing.

Arguments

startnumber
Optional starting value. Defaults to 0.

Returns

{ increment(): number; decrement(): number; value(): number; reset(): number } — An object exposing exactly four methods — the count itself lives in the closure and is unreachable from outside.

Examples

const c = createCounter();

c.increment(); // 1
c.increment(); // 2
c.value();     // 2
c.decrement(); // 1
c.reset();     // 0
const a = createCounter(10);
const b = createCounter(10);

a.increment(); // 11
b.value();     // 10 — a and b share nothing

Each call to the factory opens a fresh scope, so counters never bleed state into each other.

What it has to do

  • increment() and decrement() return the new count.
  • value() returns the current count without changing it.
  • reset() restores the original start value and returns it.
  • The returned object's only own enumerable properties are the four methods — the count stays private.
  • Separate counters keep independent state.

Notes

  • This is the module pattern in miniature: the count is a let inside the factory, and the methods close over it. Hanging it on the returned object as a property would make it mutable from outside.
  • If you reach for a class with a #count field, you are solving the same problem a different way — closures were the pre-class answer and still work everywhere.

Stuck? The javascript course covers everything this challenge needs.

Try it yourself
Loading playground...
5 tests · +150 XP

Discussion

Sign in to post
Sign in to join the conversation.Sign in

No comments yet. Be the first to say something.