Higher-Order Functions & Callbacks
📖 Concept
A Higher-Order Function (HOF) is a function that either:
- Takes one or more functions as arguments, OR
- Returns a function as its result
A Callback is a function passed as an argument to another function, to be called later.
HOFs are everywhere in JavaScript: map, filter, reduce, forEach, setTimeout, addEventListener, Promise.then.
🏠 Real-world analogy: A HOF is like a delivery service. You give them a package (callback) and instructions. They handle the logistics and deliver the package at the right time. You don't deliver it yourself — you delegate.
💻 Code Example
1// Basic callback2function greet(name, callback) {3 const greeting = `Hello, ${name}!`;4 callback(greeting);5}6greet("Alice", (msg) => console.log(msg));78// Higher-order function that returns a function9function multiplier(factor) {10 return function(number) {11 return number * factor;12 };13}14const double = multiplier(2);15const triple = multiplier(3);16console.log(double(5)); // 1017console.log(triple(5)); // 151819// Custom HOFs20function unless(condition, fn) {21 if (!condition) fn();22}23unless(false, () => console.log("This runs!"));2425function repeat(n, action) {26 for (let i = 0; i < n; i++) action(i);27}28repeat(3, (i) => console.log(`Iteration ${i}`));2930// Practical: function composition31function compose(...fns) {32 return (x) => fns.reduceRight((acc, fn) => fn(acc), x);33}34const addOne = (x) => x + 1;35const square = (x) => x * x;36const addOneThenSquare = compose(square, addOne);37console.log(addOneThenSquare(4)); // 25 = (4+1)²3839// Callbacks in async operations40function fetchData(url, onSuccess, onError) {41 // Simulating async operation42 setTimeout(() => {43 const success = Math.random() > 0.3;44 if (success) onSuccess({ data: "result" });45 else onError(new Error("Failed to fetch"));46 }, 1000);47}48fetchData("/api",49 (data) => console.log("Success:", data),50 (err) => console.error("Error:", err)51);
🏋️ Practice Exercise
Mini Exercise:
- Write a HOF
retry(fn, n)that callsfnup tontimes until it succeeds - Implement your own
mapandfilterfunctions using callbacks - Create a
pipefunction (like compose but left-to-right) - Write a
throttlefunction that limits callback execution to once per interval
⚠️ Common Mistakes
Passing the result of a function instead of the function itself:
setTimeout(greet(), 1000)calls greet immediatelyNot handling errors in callbacks — always have an error-first callback pattern or error handler
Creating deeply nested callbacks (callback hell) — use Promises or async/await instead
Losing
thiscontext when passing methods as callbacks — use.bind()or arrow functionsNot understanding that callbacks can be synchronous too —
array.map(fn)callsfnsynchronously
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for Higher-Order Functions & Callbacks. Login to unlock this feature.