Last week, I casually dropped the term “higher-order function” when talking about memoization. While I feel comfortable throwing around terms like that now, I didn’t always know what they meant. This week we’ll examine what higher-order functions are, show some common examples, and learn how to go about creating our own.
At its core, a higher-order function is just a function that accepts a function as an argument or returns a function. This is possible in JavaScript thanks to first-class functions, which means that functions in JavaScript can be passed around like any other variable. While this sounds pretty straightforward, it doesn’t quite telegraph the kind of power you have with first-class functions.
If you write JavaScript, you have probably used higher-order functions and not even noticed. If you have ever replaced a for
loop with an array method, you’ve used higher-order functions. If you have ever used the results of an AJAX call (without async
/await
), you’ve used higher-order functions (both promises and callbacks involve higher-order functions). If you have ever written a React component that displays a list of items, you’ve used higher-order functions. Let’s see those examples:
const items = ['a', 'b', 'c', 'd', 'e']
// Instead of this for loop....
for(let i = 0; i < items.length - 1; i++) {
console.log(items[i]);
}// We can use forEach, a higher-order function
// (forEach takes a function as an argument)
items.forEach((item) => console.log(item));// Callbacks or promises, if you’re making
// asynchronous requests, you’re using
// higher-order functions
get('https://aws.random.cat/meow', (response) => {
putImageOnScreen(response.file);
});
get('https://random.dog/woof.json').then((response) => {
putImageOnScreen(response.file);
});// In the React component below, map is used,
// which is a higher-order function
const myListComponent = (props) => {
return (
<ul>
{props.items.map((item) => {
return (<li key={item}>{item}</li>)
})}
</ul>
);
};
Those are examples of higher-order functions that accept functions as arguments, but plenty of them return functions as well. If you’ve ever seen a function call that has two sets of parentheses, that’s a higher-order function. This sort of thing used to be less common, but if you work with Redux at all, you’ve probably used the connect
function, which is a higher-order function:
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);