What you'll learn
A closure is a function paired with the lexical environment where it was created. It lets behavior carry durable, private state without exposing that state globally.
By the end of this lesson, you'll be able to:
- Explain what a closure retains
- Build stateful factory functions
- Recognize closure lifetime and memory tradeoffs
Core mental model
Use this decision table as a compact reference. Focus on what each tool means and when it earns its place in production code.
| Concept | What it means | Decision rule |
|---|---|---|
| Captured binding | A function retains access to outer names | Capture only state the returned behavior needs |
| Factory | Each call creates independent state and behavior | Use factories for configurable instances |
| Private state | Data is reachable only through returned functions | Expose operations instead of raw mutable data |
Professional workflow
Build the behavior in small, observable steps. Each step should leave something you can inspect or test.
- Describe the closure boundary: inputs, outputs, state, timing, and expected failures.
- Implement the smallest correct path with names that expose intent.
- Add edge cases and failure handling before introducing abstractions.
- Verify behavior with realistic data and one deliberately adversarial example.
- Refactor only after the observable behavior is protected.
Make behavior observable
Guided code lab
Create an independent counter
Every factory call receives a separate count binding.
function createCounter(start = 0) {
let count = start;
return {
next() { count += 1; return count; },
current() { return count; },
};
}
const counter = createCounter(10);
console.log(counter.next(), counter.next(), counter.current());Configure a reusable validator
The rule is captured once and applied to many values.
function atLeast(minimum) {
return value => value >= minimum;
}
const isAdult = atLeast(18);
console.log(isAdult(16));
console.log(isAdult(21));Production practice
Contract
Returned functions form the public API; captured state remains an implementation detail.
Verification
Create two instances and prove their state evolves independently.
Operations
Release references to long-lived closures when their work is finished.
Common failure mode
Independent workshop
Build a shopping-cart factory with add, remove, total, and snapshot operations.
Your finished workshop must include:
- Private item storage
- Independent cart instances
- Snapshots that callers cannot mutate
Definition of done
Recap & quick check
Key takeaways
- Closures retain lexical access
- Factories create independent environments
- Private state is exposed through operations
- Retained references affect memory lifetime
Quick check
1. What does a closure preserve?
2. Why call a factory twice?
3. When can captured state be collected?
Keep the workshop. Later modules deliberately build on these decisions, so each exercise can become part of your final portfolio architecture.