Factory Functions with Closures
A factory function creates and returns functions that retain access to state from their creation context. Each call to the factory creates a separate closure, so instances can maintain independent private state.
A closure is formed when a function retains access to variables from its surrounding lexical scope after that outer scope has finished executing. A factory function uses this behavior to produce customized functions with state that is not directly exposed to callers.
Each invocation of the factory creates a new lexical environment. The returned function closes over that particular environment, so changing state through one returned function does not change the corresponding state captured by another invocation.
This pattern is useful for encapsulation, reusable behavior, and small stateful objects without exposing their internal variables. In frontend code, it can be used for counters, configuration-bound handlers, memoized operations, and lightweight state containers.
The important distinction is that the factory creates the closure, while the returned function uses the captured state. If several returned functions are created from the same invocation, they can intentionally share that invocation's captured variables.
Key points
- A factory function can return a function that captures local state.
- Every factory invocation normally creates a distinct captured environment.
- Captured variables remain available while a returned closure can still reach them.
- Closures provide encapsulation without requiring direct access to internal variables.
Interview questions
How does a factory function use a closure to create private state?
The factory declares state inside its own local scope and returns a function that references that state. The returned function forms a closure over the environment containing the variable. Because callers cannot directly access that local variable, the returned function can control how the state changes. A new factory call creates a separate environment and therefore separate state.
Why do two closures returned from separate factory calls not share state?
Each factory invocation creates its own execution context and local bindings. A returned closure retains a reference to the environment created for that particular invocation. Consequently, the closure from the first call accesses a different binding from the closure produced by the second call. Their state is independent unless both closures deliberately capture a shared variable.
When would you choose a closure-based factory over a class in frontend code?
A closure-based factory is useful when the main goal is a small API with encapsulated state and there is no need for class inheritance or prototype-based methods. It can make private implementation details straightforward because the state lives in the lexical environment. A class may be more appropriate when the application benefits from inheritance, explicit instance structure, or a conventional object-oriented API. The choice should follow the required interface and maintainability needs rather than treating either pattern as universally superior.
Can multiple returned functions from one factory invocation share private state?
Yes. If a factory creates several functions that reference the same local variable, those functions close over the same lexical environment. Mutating that variable through one returned function can therefore affect what another returned function observes. This is different from calling the factory twice, because separate invocations normally establish separate environments. The shared environment can be useful when designing a small encapsulated API.