JavaScript has the ability to compose so many different kinds of functions together that can eventually lead to a working program.
We see JavaScript code everywhere which demonstrates this in different ways.
Composing functions together can become extremely fun, especially when they work.
Unfortunately, it’s not always an easy thing to pull off because writing composed code has to be done without any errors or otherwise, it simply won’t run. In JavaScript, there are rules to composing things, like functions, together.
What Does It Mean to Compose?
Composing means to combine more than one thing to build a bigger thing. It’s a general concept in mathematics where you combine two or more functions into a brand new function.
Most programmers have been working with this concept growing up in school, in the form of something like f(g(x)) which is pronounced “f of g of x”.
Let’s talk about composing functions. When we compose functions together, the main goal is to take a function and combine it with another function, so that when both of them are together, it gives us a more enhanced function that helps to produce a value that we want.
There are multiple good reasons why people prefer to compose functions, such as reducing code and providing a more convenient reusable piece of code.
In JavaScript, functions are considered first-class, meaning they can be passed around and can take on the disguise of a “value”, just like strings, numbers, booleans, objects, etc.
What it means is that it allows functions to take other functions as arguments and can even return functions. This is what makes JavaScript a very powerful language because you can throw them around anywhere you want.
Why Is It Important to Compose?
The doubleTheNums function is responsible for looking at an object and doubling its number value if it’s a number type.
Why should we turn this into a composed function instead? Let’s look at some problems that the current function is having first:
- If the object passed in was deeply nested, the code will just keep awkwardly being pushed down right like a tree shape. But no one has time for that kind of thing.
- If the object passed in was deeply nested, we unnecessarily lose valuable brain energy running out of ideas to name the inner variables (innerObjKey, innerObjKeyValue might lead to deeplyInnerObjKey, deeplyInnerObjKeyValue, innerInnerInnerObjKey, innerInnerInnerObjKeyValue, etc.)
- The code gets repetitive over time. This might confuse us and no one wants to be confused.
- File size is increasing.
If you’ve looked at source codes of JavaScript libraries then you’ve probably been exposed to a good amount of code examples that do really well in composing functions.
You might have also realized that the majority of these composed functions are composed of much smaller, modular functions.
Injecting Callbacks to Be Used in Conjunction With Existing Ones
The possibilities of good uses for composing functions are endless. But to wrap this article up, we’ll go over another useful use case so that you can have a better understanding of how functions can be composed to achieve a variety of scenarios.
In callAll, a .forEach ensured that each function in the pipeline received the event object each time because, by definition, it doesn’t return anything to the caller even if it tried to return one.