Closures and Higher-Order Functions in JavaScript
Higher-order functions rely on closures. Here is how map, filter, reduce, and custom HOFs use them.
Closures and Higher-Order Functions in JavaScript
A higher-order function is a function that takes a function as an argument, returns a function, or both. Closures are what make them work.
How HOFs Use Closures
When a HOF takes a callback, the callback closes over variables from where it was defined. When a HOF returns a function, the returned function closes over the HOF's local variables.
map, filter, reduce
const multiplier = 3; const result = [1, 2, 3].map((n) => n * multiplier); // [3, 6, 9] `` The `map` callback closes over `multiplier`. Without closures, the callback could not access outer variables. ### Custom HOF: `compose` ```js function compose(f, g) { return (x) => f(g(x)); } const addOne = (n) => n + 1; const double = (n) => n * 2; const addOneThenDouble = compose(double, addOne); addOneThenDouble(5); // 12 (addOne(5) = 6, double(6) = 12) `` `compose` returns a function that closes over `f` and `g`. Each call to the returned function invokes `f(g(x))`. ### Custom HOF: `partial` ```js function partial(fn, ...presetArgs) { return (...laterArgs) => fn(...presetArgs, ...laterArgs); } const add = (a, b, c) => a + b + c; const add5 = partial(add, 5); add5(3, 2); // 10 `` `partial` returns a function that closes over `fn` and `presetArgs`. ### Custom HOF: `curry` ```js function curry(fn) { return function curried(...args) { if (args.length >= fn.length) return fn(...args); return (...next) => curried(...args, ...next); }; } const sum = curry((a, b, c) => a + b + c); sum(1)(2)(3); // 6 `` `curry` returns a chain of functions, each closing over the accumulated arguments. ### HOFs and the Event Loop ```js function withTimeout(fn, delay) { return (...args) => setTimeout(() => fn(...args), delay); } const delayedLog = withTimeout(console.log, 1000); delayedLog("hello"); // logs "hello" after 1 second `` The returned function closes over `fn` and `delay`. When called, it schedules `fn` via `setTimeout`. ### The Takeaway Higher-order functions rely on closures: callbacks close over outer variables, and returned functions close over the HOF's local variables. `map`/`filter`/`reduce` callbacks, `compose`, `partial`, `curry`, and `withTimeout` all use closures. Understanding this makes functional programming in JS click.
When a HOF takes a callback, the callback closes over variables from where it was defined. When a HOF returns a function, the returned function closes over the HOF's local variables. Closures are what make HOFs work.
The callback passed to map closes over variables from where the callback was defined. For example, [1, 2, 3].map(n => n * multiplier) works because the arrow closes over the outer multiplier variable.
compose(f, g) returns a function that closes over f and g. Each call to the returned function invokes f(g(x)). The closure keeps f and g alive so the returned function can use them later.
Yes. They take a callback function as an argument, which makes them higher-order. The callbacks close over outer variables, which is why you can reference outer state inside them.
Closures enable functional programming: currying, partial application, composition, and higher-order functions all rely on closures to capture variables. Without closures, returned functions could not access outer variables, and functional patterns would not work.
Ready to master React completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master React
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

