Callbacks and Higher-Order Functions
This note is complete, reviewed, and considered stable.
In JavaScript, callbacks and higher-order functions are key concepts, especially when dealing with asynchronous programming, functional programming paradigms, and code modularity.
Callbacks
A callback is a function that is passed as an argument to another function, which is then executed after a certain event or condition is met. Callbacks allow you to control the flow of execution in asynchronous operations and handle results when they're ready.
Characteristics of Callbacks
- Asynchronous: Callbacks are often used in asynchronous operations such as reading files, making API calls, or processing user input.
- Synchronous: They can also be used for synchronous operations, though they are most commonly associated with asynchronous programming.
Example of a Callback Function
function fetchData(callback) {
// Simulating asynchronous data fetching
setTimeout(() => {
const data = { userId: 1, name: "Alice" };
callback(data); // Passing data to the callback function
}, 2000);
}
function displayData(data) {
console.log("User Data:", data);
}
// Calling fetchData and passing displayData as the callback
fetchData(displayData);
In the above example:
fetchDatasimulates fetching data asynchronously and accepts a callback (displayData).- Once the data is fetched, it is passed to the
displayDatafunction as an argument.
Callback as an Anonymous Function
function fetchData(callback) {
setTimeout(() => {
const data = { userId: 1, name: "Bob" };
callback(data);
}, 2000);
}
fetchData(function (data) {
console.log("User Data:", data);
});
Higher-Order Functions
A higher-order function is a function that either:
- Takes one or more functions as arguments, or
- Returns a function as a result.
Higher-order functions are a fundamental concept in functional programming and help promote more reusable and modular code.
Characteristics of Higher-Order Functions
- They allow functions to be treated as first-class citizens, meaning they can be passed around as arguments, returned from other functions, and assigned to variables.
- Higher-order functions are often used in callbacks, event handlers, and when working with functional libraries like Lodash.
Example 1: Function that Takes Another Function as an Argument
function greet(name, callback) {
const greeting = `Hello, ${name}!`;
callback(greeting); // Passing greeting to callback
}
greet("Alice", function (message) {
console.log(message); // Output: Hello, Alice!
});
Here, the greet function is a higher-order function because it takes another function (callback) as an argument and calls it inside.
Example 2: Function that Returns Another Function
function multiplyBy(factor) {
return function (number) {
return number * factor;
};
}
const multiplyByTwo = multiplyBy(2);
console.log(multiplyByTwo(5)); // Output: 10
const multiplyByThree = multiplyBy(3);
console.log(multiplyByThree(5)); // Output: 15
In this example:
- The
multiplyByfunction returns a new function that can multiply a number by a given factor. - The returned function (e.g.,
multiplyByTwo) is then invoked with specific values.
Example 3: Array Methods as Higher-Order Functions
Many JavaScript array methods, like map(), filter(), and reduce(), are examples of higher-order functions because they take a function as an argument.
const numbers = [1, 2, 3, 4, 5];
// Using map, which is a higher-order function
const doubledNumbers = numbers.map(function (num) {
return num * 2;
});
console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10]
Key Differences Between Callbacks and Higher-Order Functions
| Aspect | Callback | Higher-Order Function |
|---|---|---|
| Definition | A function passed as an argument to another function. | A function that either takes one or more functions as arguments or returns a function. |
| Purpose | Used to handle asynchronous operations or pass a function to another for execution later. | Used to create more reusable, modular, and composable functions. |
| Example | setTimeout() accepting a function as the callback. | map() or filter() array methods that take a function as an argument. |
| Return Value | Typically, callbacks do not return a value; they are executed later. | Can return a new function or modify a data structure. |
| Typical Use Case | Asynchronous handling, event handling, error handling. | Functional programming, creating abstractions, functional composition. |