Higher-Order Functions in JavaScript

7 min read·Jan 1, 2025

As opposed to a first-order function, a higher-order function is a function that takes other functions as argument:

function higherOrder(firstClass) {
  // ...
}

Or returns a function as its result:

function higherOrder() {
  return function() {
    // ...
  }
}

When supplied as an argument or returned as a value, these functions are called first-class functions.

Note: First-class functions that are typically executed in response to an event but not returned are usually called callback functions.

function higherOrder(callback) {
  callback();
}

Example

Let's consider this script, that uses a higher-order function to perform simple arithmetic calculation:

calculate.js
function calculate(a, b, fn) {
  return fn(a, b);
}

const add = (a, b) => a + b;

const multiply = (a, b) => a * b;

const sum = calculate(3, 2, add);
console.log(sum);

const product = calculate(3, 2, multiply);
console.log(product);

When executed, it will:

  1. Define a function named calculate that returns the execution result of its callback function fn and its two parameters a and b.
  2. Declare a variable named add and initialize it with an anonymous function that returns the sum of its parameters a and b.
  3. Declare a variable named multiply and initialize it with an anonymous function that returns the product of its parameters a and b.
  4. Execute the calculate function with two integers and the add function and store its result into the sum variable.
  5. Output the value of the sum variable.
  6. Execute the calculate function with two integers and the multiply function and store its result into the product variable.
  7. Output the value of the product variable.

Which will produce this output:

$ node calculate.js
5
6

Note: Since the functions stored in the add and multiply variables are anonymous, they can also be directly declared as an argument of the calculate function during its invocation:

const sum = calculate(1, 2, (a, b) => a + b);
const product = calculate(1, 2, (a, b) => a * b);

Closures

A closure is a function that has access to its own scope, the scope of the outer function, and the global scope.

It keeps track of the variables that are in scope at the time of its creation, and can still access them even after the outer function has finished executing.

Example

Let's consider this script, that implements a closure whose return function still has access to a local scope variable after its creation:

create_counter.js
function createCounter() {
  let count = 0;

  return function () {
    count = count + 1;
    return count;
  };
}

const counter = createCounter();

console.log(counter());
console.log(counter());
console.log(counter());

When executed, it will:

  1. Define a function named createCounter.

    1. Declare a local variable named count and initialize it to 0.
    2. Return an anonymous function that increments the value of the count variable by 1 and returns it.
  2. Execute the createCounter function and store its result into the counter variable.

  3. Execute the counter variable as a function 3 times and output its return value.

Which will produce this output:

$ node create_counter.js
1
2
3

Enjoying the courses?

I've made these courses completely free so anyone can learn from them. If they've helped you and you'd like to actively support the work behind BackendBrewery, you can leave a tip:

Support BackendBrewery
(Bonus) Higher-Order Functions in JavaScript | Backend Brewery