Course outline · 0% complete

0/27 lessons0%

Course overview →

Private state and the module pattern

lesson 1-3 · ~12 min · 3/27

The module pattern

In lesson 1-2 a closure returned one function. Return an object of functions instead, and they all share the same closed-over variables. That is the module pattern: a maker function whose local variables become private state, and whose returned object is the public API.

Nothing outside can touch balance directly. There is no account.balance property at all. The only way in is through the functions you chose to expose.

This pattern is everywhere in real code: database clients that hide their connection state, caches that hide their storage, counters and ID generators. Before class syntax existed it was THE way JavaScript libraries organized themselves, and it is still the cleanest choice when one object needs genuinely private state.

Code exercise · javascript

Run it. `balance` is a local variable, not a property. Reading `account.balance` gives `undefined`, and the real balance is untouched.

Quiz

A user runs `account.balance = 9999;` on the account above, then calls `account.getBalance()`. What does it return?

Worked example: memoize

A cache is a store of already-computed results you can return instead of recomputing them. memoize(fn) wraps a function with a private cache object: the closure records each result under its input, and a repeat call returns the stored answer without running fn again. The cache is a closed-over variable, so no other code can read or corrupt it — the same privacy balance had, applied to performance.

Code exercise · javascript

Run it. The first `square(4)` computes and stores; the second finds 16 already in the closed-over cache. Nothing outside can touch `cache` — there is no property to poke at, only the wrapped function.

Closures capture variables, not values

The #1 closure interview trap. A closure holds a link to the variable, so it sees the variable's latest value, not the value from when the closure was created.

With var, a loop has one shared i, and every closure created in the loop links to that same variable, which ends up at 3. With let, each loop iteration gets a fresh i, so each closure captures its own.

Code exercise · javascript

Run it and compare the two halves. Same loop, different keyword, different result. Be ready to explain why in an interview.

Code exercise · javascript

Your turn. Build a `createPlaylist()` module with private array `songs`, an `add(title)` function, and a `summary()` function returning `"<count> songs: <titles joined by ', '>"`.