liveBook · Manning

Higher-order function

As explained in The Joy of JavaScript

A higher-order function is a function that takes one or more functions as arguments and/or returns a function as its result.

A higher-order function accepts a function as an argument, returns a function, or both. JavaScript can pass functions around because functions are objects. The practical payoff is behavioral composition: small pieces of logic can be supplied as callbacks or connected into a sequence instead of being embedded in one large procedure. section 4.0

Array methods such as filter, map, and reduce provide the sequence; their callbacks supply the application-specific decisions. This separates the mechanics of traversing an array from the logic applied to each element. Unlike mutating methods such as sort and reverse, the filter-and-map example leaves its original array intact—an important distinction when other code still uses that array. section 4.1

Listing 4.1 Combining map, filter, and reduce
const arr = [b1, b2, b3];
 
arr
   .filter(b => !b.isGenesis())         #1
   .map(b => b.isValid())               #2
   .reduce((a, b) => a && b, true);     #3

The chain skips a genesis block, checks the remaining blocks, then combines the Boolean results. Each callback states one decision without managing a loop. section 4.1

Return a function to make composition fit

Suppose assemble needs both a list of keys and an object, but the next step of a composition expects a function that takes the object. Define `function assemble(keys) { return function (obj) { return keys.map(f => obj[f]).join(''); }; }`. Calling `assemble(keys)` now returns the function the composition needs. Its closure retains `keys`, while the returned function waits for `obj`. This is a curried form of the original two-argument operation. section 4.3.2

Higher-order functions can also wrap repeated concerns around a sequence of operations. For example, mapping a validation wrapper over a list of functions removes repeated checks from a composition. A wrapper still has to apply its supplied function to valid data; checking the data alone does not execute the operation. When validation and errors need richer handling, a validation data type offers another level of abstraction. section 5.1 section 5.0

The same design extends beyond arrays. Pipeable observable operators are higher-order functions: supplied functions express business logic while operators transform data flowing through an observable. Across these uses, the aim is declarative code assembled from smaller behaviors, not merely fewer lines of code. section 1.5 section 4.9

How The Joy of JavaScript covers it

How deep it goes
Defines the function-passing pattern and works through array callbacks, returned closures, and validation wrappers; leaves richer validation to data types.
Examples
Shows block validation with filter, map, and reduce; returns an object-processing function from assemble; wraps functions with a null check.
What it assumes
Assumes familiarity with JavaScript functions and array APIs, while explaining how their callbacks support functional programming.
What you can do after
Build it from scratch by returning functions that retain inputs, and apply it via array methods to compose smaller operations.
How it connects
Connects higher-order functions to closures, currying, pure functions, composition, immutability, and algebraic data types.

Also explained in

Compare how 14 books explain higher-order function →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Joy of JavaScript. The section links point to the parts of the book it draws on.