Function composition in JavaScript is a technique that combines two or more functions to create a new function. The output of one function becomes the input of another function. This approach helps developers break complex operations into smaller, reusable functions.
Function composition is commonly used in functional programming, data transformation, and JavaScript applications.
What Is Function Composition in JavaScript?
Function composition means combining functions so that they execute in a specific order, passing the result from one function to the next.
For example, imagine you want to perform two operations:
- Multiply a number by 2.
- Add 5 to the result.
Instead of writing both operations together, you can create two separate functions and compose them.
function multiply(number) {
return number * 2;
}
function add(number) {
return number + 5;
}
const result = add(multiply(10));
console.log(result);
Output:
25
Here is how the code works:
multiply(10)returns20.add(20)returns25.- The final result is
25.
The output of the multiply() function becomes the input of the add() function. This is a basic example of function composition.
How Does Function Composition Work?
Function composition works by connecting multiple functions together. Each function performs one task and returns a value that another function can use.
Consider the following example:
function double(number) {
return number * 2;
}
function square(number) {
return number * number;
}
function addTen(number) {
return number + 10;
}
const result = addTen(square(double(3)));
console.log(result);
Output:
46
Let’s understand the execution step by step:
double(3)returns6.square(6)returns36.addTen(36)returns46.
The functions execute from the innermost call to the outermost call.
Although this approach works, deeply nested function calls can become difficult to read. A reusable composition function can make the code cleaner.
Creating a Function Composition Helper
JavaScript does not provide a built-in general-purpose compose() function. However, you can create your own helper using functions and the reduceRight() array method.
function compose(...functions) {
return function (value) {
return functions.reduceRight(
(result, fn) => fn(result),
value
);
};
}
function double(number) {
return number * 2;
}
function addFive(number) {
return number + 5;
}
const calculate = compose(addFive, double);
console.log(calculate(10));
Output:
25
In this example, compose() accepts multiple functions as arguments.
The reduceRight() method processes the functions from right to left:
double(10)returns20.addFive(20)returns25.
The calculate() function now combines both operations into a single reusable function.
Notice that compose(addFive, double) lists addFive first, but double executes first. This is because composition proceeds from right to left.
Function Composition Using Arrow Functions
You can also use arrow functions to write function composition in a shorter and more readable way.
const double = number => number * 2;
const addFive = number => number + 5;
const subtractTwo = number => number - 2;
const result = subtractTwo(addFive(double(10)));
console.log(result);
Output:
23
The execution order is:
double(10)returns20.addFive(20)returns25.subtractTwo(25)returns23.
Arrow functions are useful when the operations are short and straightforward.
Function Composition vs. Calling Functions Separately
Both approaches can produce the same result, but composition can make a sequence of operations easier to reuse.
| Calling functions separately | Function composition |
|---|---|
| Operations may be repeated across the code. | Operations can be combined into a reusable function. |
| Each sequence may need to be written again. | The composed function can be called multiple times. |
| Simple for a small number of operations. | Useful for connecting multiple transformations. |
| Can become difficult to maintain when repeated. | Can improve organization when functions have clear responsibilities. |
Function composition is especially helpful when you need to apply the same sequence of transformations to different values.
Benefits of Function Composition
Function composition offers several advantages:
- Code reusability: Combine existing functions without rewriting their logic.
- Better organization: Keep each function focused on a single task.
- Easier testing: Test individual functions independently.
- Improved maintainability: Update one operation without rewriting the entire sequence.
- Readable transformations: Represent a series of operations as one reusable function.
For the best results, keep composed functions small and ensure that each function returns a value in the format expected by the next function.
Function Composition in Real-World Applications
Function composition is useful when processing user input, formatting data, or transforming values before displaying them.
For example, you might want to trim whitespace from a name and convert it to uppercase.
function trimText(text) {
return text.trim();
}
function toUpperCase(text) {
return text.toUpperCase();
}
function compose(...functions) {
return function (value) {
return functions.reduceRight(
(result, fn) => fn(result),
value
);
};
}
const formatName = compose(toUpperCase, trimText);
console.log(formatName(" karimulla "));
Output:
KARIMULLA
The trimText() function removes whitespace from the beginning and end of the string. The toUpperCase() function then converts the cleaned text to uppercase.
By composing these functions, you can reuse the same formatting process wherever it is needed.
Frequently Asked Questions
What is function composition in JavaScript?
Function composition is a programming technique in which multiple functions are combined so that the result of one function becomes the input of another.
Why is function composition useful?
It improves code reuse, organization, testability, and maintainability by allowing developers to combine small functions into larger operations.
Does JavaScript have a built-in compose() function?
No. JavaScript does not provide a general-purpose built-in compose() function. Developers can create one or use functional programming libraries.
What is the difference between compose() and pipe()?
Both combine functions, but they typically differ in execution direction. compose() usually executes functions from right to left, while pipe() usually executes them from left to right.
Can function composition work with arrow functions?
Yes. Arrow functions can be composed in the same way as regular functions, provided each function returns a value that the next function can accept.
Is function composition the same as a higher-order function?
No. Function composition is a technique for combining functions. A higher-order function is a function that accepts another function as an argument, returns a function, or does both. A composition helper is an example of a higher-order function.