Introduction
Higher-Order Functions (HOFs) take functions as arguments or return functions. They're the building blocks of functional composition.
Key Concepts
First-Class Functions: Functions can be stored, passed, and returned.
HOF: A function that operates on other functions.
Abstraction: HOFs abstract common patterns.
Real World Context
React hooks like useCallback, useMemo, and useEffect are HOFs—they take functions as arguments. Express middleware takes (req, res, next) => {} callbacks. Array methods map, filter, reduce are the most commonly used HOFs in any JavaScript codebase. ES2025 Iterator helpers add .map(), .filter() directly on iterators.
Deep Dive
Functions as Arguments
javascript// map, filter, reduce are HOFs const numbers = [1, 2, 3, 4, 5]; numbers.map(x => x * 2); // [2, 4, 6, 8, 10] numbers.filter(x => x > 2); // [3, 4, 5] numbers.reduce((sum, x) => sum + x, 0); // 15
Functions Returning Functions
javascriptfunction multiply(factor) { return function(number) { return number * factor; }; } const double = multiply(2); const triple = multiply(3); double(5); // 10 triple(5); // 15
Creating HOFs
javascript// Repeat an action n times function times(n) { return function(action) { for (let i = 0; i < n; i++) action(i); }; } times(3)(i => console.log(i)); // 0, 1, 2 // Unless - inverse of filter function unless(predicate) { return function(action) { return function(value) { if (!predicate(value)) action(value); }; }; }
Common Pitfalls
- Accidental closure over stale values — A returned function captures variables by reference, not value. In loops, this often causes bugs where all closures share the same variable.
- Overusing HOFs for simple tasks —
arr.map(x => x)to clone an array is less clear than[...arr]. Use HOFs when they add clarity. - Ignoring
thisbinding — Arrow functions capturethislexically, butfunctionexpressions don't. Returning afunctionfrom a HOF can losethiscontext.
Best Practices
- Name returned functions — Instead of returning anonymous functions, give them names for better stack traces:
return function handleClick() { ... }. - Keep HOFs focused — A HOF should do one thing: add logging, add caching, add validation—not all three.
- Use ES2025 Iterator helpers for lazy HOFs —
iterator.map(fn).filter(pred).take(n)processes lazily without intermediate arrays.
Summary
HOFs take or return functions. map/filter/reduce are common HOFs. Use them to abstract patterns and create reusable utilities.
Code Examples
javascript
// HOFs take functions as arguments or return functions
const numbers = [1, 2, 3, 4, 5];
// Built-in HOFs
numbers.map(x => x * 2); // [2, 4, 6, 8, 10]
numbers.filter(x => x > 2); // [3, 4, 5]
numbers.reduce((sum, x) => sum + x, 0); // 15
// Creating a HOF that returns a function
function multiply(factor) {
return function(number) {
return number * factor;
};
}
const double = multiply(2);
const triple = multiply(3);
double(5); // 10
triple(5); // 15