Higher-Order Functions (HOF)
HOF = function that takes a function and/or returns a function
What is a Higher-Order Function?
"Function as argument or return value"
A higher-order function is a function that:
- Takes one or more functions as arguments, or
- Returns a function
Memory hook
"HOF = functions are first-class: pass them in, return them out"
Why HOF?
- Abstraction — reuse logic (e.g. map, filter, reduce)
- Composition — build behavior from smaller functions
- Callbacks — event handlers, async, array methods
- Decorators / wrappers — add behavior around a function
1. Function as argument
Pass a function to customize behavior
// Callback
function repeat(n, fn) {
for (let i = 0; i < n; i++) fn(i);
}
repeat(3, (i) => console.log(i)); // 0, 1, 2
// Array methods (all HOFs)
[1, 2, 3].map((x) => x * 2); // [2, 4, 6]
[1, 2, 3].filter((x) => x > 1); // [2, 3]
[1, 2, 3].reduce((acc, x) => acc + x, 0); // 6
2. Function as return value
Return a function to create specialized behavior
function multiplyBy(factor) {
return (x) => x * factor;
}
const double = multiplyBy(2);
const triple = multiplyBy(3);
double(5); // 10
triple(5); // 15
3. Both: take and return functions
Wrapper / decorator pattern
function withLog(fn) {
return function (...args) {
console.log("Calling with", args);
const result = fn(...args);
console.log("Result", result);
return result;
};
}
const addLogged = withLog((a, b) => a + b);
addLogged(2, 3); // logs + returns 5
Common HOF patterns
map — transform each element
const nums = [1, 2, 3];
nums.map((x) => x * 2); // [2, 4, 6]
nums.map((x, i) => `${i}: ${x}`); // ["0: 1", "1: 2", "2: 3"]
filter — keep elements that pass a test
[1, 2, 3, 4].filter((x) => x % 2 === 0); // [2, 4]
reduce — single value from array
[1, 2, 3].reduce((acc, x) => acc + x, 0); // 6
[1, 2, 3].reduce((acc, x) => [...acc, x * 2], []); // [2, 4, 6]
forEach — side effects only (no return)
[1, 2, 3].forEach((x) => console.log(x));
find / findIndex — first match
[1, 2, 3].find((x) => x > 1); // 2
[1, 2, 3].findIndex((x) => x > 1); // 1
some / every — quantifiers
[1, 2, 3].some((x) => x > 2); // true
[1, 2, 3].every((x) => x > 0); // true
Custom HOF examples
once — run function only once
function once(fn) {
let called = false;
let result;
return function (...args) {
if (!called) {
called = true;
result = fn(...args);
}
return result;
};
}
const init = once(() => console.log("init"));
init(); // "init"
init(); // (no log)
debounce (concept)
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
curry (concept)
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) return fn(...args);
return (...next) => curried(...args, ...next);
};
}
const add = (a, b) => a + b;
const curriedAdd = curry(add);
curriedAdd(2)(3); // 5
HOF vs first-class functions
- First-class functions — functions are values (assign, pass, return).
- Higher-order function — a function that uses first-class functions by taking or returning them.
So: first-class is the language feature; HOF is the pattern that uses it.
Interview one-liner
"A higher-order function is one that takes a function as an argument or returns a function. Examples: map, filter, reduce, and decorators like withLog or once. They rely on functions being first-class in JavaScript."
Cheat sheet
HOF = takes function and/or returns function
First-class = functions are values
map / filter / reduce = classic HOFs
Decorator = HOF that returns wrapped function
Curry / once / debounce = return functions