What are higher-order functions
A higher-order function takes a function as an argument, returns a function, or both. Examples: map/filter/reduce, setTimeout, event listeners, and function factories. They're the basis of composition, currying, and decorators in JS.
A higher-order function (HOF) is a function that does at least one of:
- Takes a function as an argument, or
- Returns a function.
It's possible because in JavaScript functions are first-class values — you can pass them around, store them, and return them like any other value.
Category 1: takes a function
[1, 2, 3].map((x) => x * 2); // map takes a callback
[1, 2, 3].filter((x) => x > 1);
arr.reduce((acc, x) => acc + x, 0);
setTimeout(() => console.log("hi"), 100);
el.addEventListener("click", handler);map, filter, reduce, forEach, sort, setTimeout, event listeners — all HOFs.
Category 2: returns a function
function multiplier(factor) {
return (x) => x * factor; // returns a function
}
const double = multiplier(2);
double(5); // 10This is a function factory — and the returned function is a closure over factor.
Why they matter
- Abstraction & reuse —
mapabstracts "transform every element"; you supply only the transformation. - Composition — build complex behavior by combining small functions.
- Currying & partial application —
multiplier(2)pre-fills an argument. - Decorators / wrappers —
debounce,throttle,memoize,onceall take a function and return an enhanced version:
function once(fn) {
let called = false, result;
return (...args) => {
if (!called) { called = true; result = fn(...args); }
return result;
};
}The contrast
A first-order function only deals with data: (a, b) => a + b. A HOF deals with functions. HOFs depend on closures to be useful — the returned function "remembers" the enclosing scope.
The framing
"A higher-order function takes a function as an argument, returns one, or both — possible because JS functions are first-class values. map/filter/reduce and setTimeout are the take-a-function kind; a function factory like multiplier(2) is the return-a-function kind. They're the foundation of composition, currying, and decorators — debounce, memoize, once are all HOFs — and they lean on closures so the returned function remembers its scope."
Follow-up questions
- •What does 'first-class functions' mean?
- •How do higher-order functions relate to closures?
- •Write a `once` or `memoize` higher-order function.
- •What's currying and how does it use HOFs?
Common mistakes
- •Thinking a HOF must both take and return a function — either one qualifies.
- •Confusing higher-order functions with callbacks (a callback is the argument, not the HOF).
- •Not connecting HOFs to closures.
Performance considerations
- •HOFs allocate function objects and closures — usually negligible, but creating new functions inside hot loops or every render can add up. The clarity almost always outweighs it.
Edge cases
- •A HOF that returns a function which itself is a HOF (currying chains).
- •Losing `this` when passing a method as a callback to a HOF.
Real-world examples
- •Array methods (map/filter/reduce) used throughout any codebase.
- •debounce, throttle, memoize utilities and React HOCs.