ReviseAlgo Logo

Functions

Higher-Order Functions

Master JavaScript Higher-Order Functions (HOFs). Learn how functions accept other functions as arguments, return functions, and enable declarative programming.

Last Updated: July 15, 2026 10 min read

1. Introduction

In JavaScript, functions are First-Class Citizens, meaning they can be treated like any other value: assigned to variables, passed as arguments, and returned from other functions. A Higher-Order Function (HOF) is a function that accepts one or more functions as arguments, returns a function as its result, or both.

2. Why It Matters

HOFs enable a Declarative Programming style, helping you write abstract and reusable code. Instead of describing how to loop and update lists step-by-step, HOFs let you describe what transformation to apply.

3. Real-World Analogy

Think of a General Contractor:

  • First-Class Function (Subcontractor): A specialized electrician or plumber. You can hire them, refer them to other projects, or bring them on site to work.
  • Higher-Order Function (General Contractor): The manager who takes blueprints and hires specialized subcontractors (receives functions) to handle specific tasks (electrical, plumbing). Alternatively, the manager can assign a team leader to oversee subsequent projects (returns a new function).

4. How It Works

HOFs operate in two main patterns:

1. Accepting Functions as Arguments:

The function receives a callback wrapper to process inputs dynamically (e.g. map, filter).

2. Returning Functions:

Generates a new, customized function containing wrapped parameters inside a closure.

5. Common Built-in HOFs

Method Operation Description Callback Inputs
Array.prototype.map Transforms each element in an array, returning a new array. (element, index, array)
Array.prototype.filter Filters elements using a predicate check, returning a new array. (element, index, array)
Array.prototype.reduce Reduces an array to a single value using an accumulator. (accumulator, element, index, array)

6. Practical Example

This script demonstrates creating a custom telemetry logger HOF to measure function execution times:

7. Common Mistakes

  • Forgetting to return values inside callbacks: Array methods like map and filter require return values inside their callback functions to construct the result array correctly.
  • Over-complicating logic: Writing hard-to-follow, multi-layered HOF wrappers when a simple helper function would suffice.

8. Quick Quiz

Q1: Which of the following is a higher-order function?

A) Math.sqrt

B) Array.prototype.filter

Answer: B — Array.prototype.filter accepts a callback function as an argument, making it a Higher-Order Function.

9. Scenario-Based Challenge

The API Rate Limiter HOF:

You need to write a throttle wrapper throttle(fn, delay) that limits how often a function can run. The HOF should return a wrapper function that ignores executions if it has already run within the specified delay window. Outline the steps to build this.

10. Debugging Exercise

Identify and fix the scoping bug in the returned count function:

function createCounter() {
  return function() {
    let count = 0; // scoping issue!
    count++;
    return count;
  };
}
const next = createCounter();
console.log(next()); // 1
console.log(next()); // 1 (Expected: 2)
View Solution

Diagnosis: The variable count is initialized inside the returned function, meaning it resets to 0 every time the function is called.

Fix: Move the variable declaration to the outer scope of the returned function to create a closure:

function createCounter() {
  let count = 0; // declared in parent scope, captured in closure
  return function() {
    count++;
    return count;
  };
}

11. Interview Questions

🟢 Q1: What makes a function "first-class" in a programming language?

Answer: A language has first-class functions if it treats functions as first-class citizens. This means functions can be assigned to variables, passed as arguments to other functions, returned from other functions, and have properties and methods attached to them, just like primitive values or object instances.

12. Production Considerations

  • Avoid Callback Nesting: While chaining array methods (like .map().filter().reduce()) is declarative, intermediate arrays are created for each step, which can cause memory overhead on large datasets. Optimize critical paths by merging loops or using single-pass operations.