What you'll learn
Because functions are values, JavaScript can express policies as callbacks, build behavior with composition, and solve recursive problems without hard-coding every operation.
By the end of this lesson, you'll be able to:
- Design higher-order utilities
- Write safe recursive functions
- Compose small transformations
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 |
|---|---|---|
| Callback | Behavior passed into another function | Pass policy when the algorithm stays the same |
| Recursion | A function solves a smaller version of its problem | Require a clear base case and decreasing input |
| Composition | Output from one function becomes input to another | Compose pure, single-purpose transformations |
Professional workflow
Build the behavior in small, observable steps. Each step should leave something you can inspect or test.
- Describe the higher-order function 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
Inject a selection policy
The reusable selector does not know what qualifies; the callback owns that decision.
function select(values, predicate) {
const result = [];
for (const value of values) if (predicate(value)) result.push(value);
return result;
}
console.log(select([3, 8, 11, 14], value => value % 2 === 0));Recurse through nested data
Each call reduces the problem to child nodes and stops at primitive values.
function countValues(value) {
if (!Array.isArray(value)) return 1;
let total = 0;
for (const item of value) total += countValues(item);
return total;
}
console.log(countValues([1, [2, 3], [[4]]]));Production practice
Contract
Document what the callback receives, returns, and whether call order matters.
Verification
Test empty input, one element, nested input, and a callback that rejects everything.
Operations
Name composed stages so stack traces and metrics remain understandable.
Common failure mode
Independent workshop
Create a transformation pipeline for product records: validate, normalize, discount, and format.
Your finished workshop must include:
- At least three pure stages
- One reusable higher-order helper
- Edge cases for invalid and empty input
Definition of done
Recap & quick check
Key takeaways
- Functions are first-class values
- Callbacks separate policy from mechanism
- Recursion needs a base case
- Composition works best with pure stages
Quick check
1. What is a higher-order function?
2. What prevents endless recursion?
3. What functions compose most predictably?
Keep the workshop. Later modules deliberately build on these decisions, so each exercise can become part of your final portfolio architecture.