35 min·intermediate

Lesson 3

Higher-order functions

Build a practical mental model for higher-order functions and use it in working JavaScript.

By the end, you will be able to…

  • Explain higher-order functions in your own words
  • Use higher-order functions in a small program
  • Recognize and debug a common failure mode

Build the mental model

A higher-order function either takes a function as an argument, returns one, or both. map, filter, and reduce are higher-order functions you already use; withLogging shows how to write your own.

Syntax and working example

Read the code from inputs to output. Predict what it prints, then run it and change one value.

Working example
Expected output: calling with [2, 3] 5

Why this matters

Higher-order functions let you inject behavior (logging, caching, retrying) around any function without duplicating code inside each one.

Real-world example

Debounce, throttle, and memoize — all upcoming lessons — are higher-order functions that wrap any function with extra behavior.

Common mistakes

  • Forgetting to forward all arguments with ...args when wrapping a function
  • Forgetting to return the wrapped function's result
  • Confusing 'takes a callback' (like map) with 'higher-order function' as if they were unrelated ideas

Try it yourself

Challenge

Write withRetryCount(fn) that returns a wrapper counting how many times it has been called.

Practice

Knowledge check

What makes a function 'higher-order'?

Summary

A higher-order function takes and/or returns a function, letting you compose new behavior around existing logic.