Build a counter with a closure

“Counter factory”, a Green belt challenge from the CurlyScript Dojo. It uses what Grade 9: Scope, Hoisting & Closures teaches, and 3 tests check your answer.

The challenge

Write makeCounter(start, step) that returns a function. Each time that function is called, it returns the next number: first start + step, then start + 2 × step, and so on. Each counter must be independent.

Example
const byTwo = makeCounter(0, 2);
byTwo();  // 2
byTwo();  // 4

Try it

Write your answer below, then press Check my answer. Your code runs right here in your browser, and the tests tell you what works.

What the tests check

  • Counting by 2 from 0 gives 2, then 4: (() => { const c = makeCounter(0, 2); c(); return c(); })() gives 4
  • Counting down from 10 gives 9: (() => { const c = makeCounter(10, -1); return c(); })() gives 9
  • Counters don’t share: (() => { const a = makeCounter(0, 1); const b = makeCounter(0, 1); a(); a(); return b(); })() gives 1

Hints

Stuck? Open one hint at a time. Try again after each one.

Hint 1

Keep a let current = start; inside makeCounter, and return a function that changes it.

Hint 2

Each call to makeCounter creates a fresh current, so counters are independent.

A solution

There’s always more than one right way. Read it, make sure you understand it, then try writing it yourself without looking.

Show one possible solution
Solution
function makeCounter(start, step) {
  let current = start;
  return () => {
    current += step;
    return current;
  };
}

Learn what you need

This exercise uses what Grade 9: Scope, Hoisting & Closures teaches. Read those notes first if any of it is new.

Practice makes it stick

CurlyScript is a free game that teaches JavaScript from zero: short lessons, an explanation after every answer, and Dojo challenges like this one.

Start learning