
Introduction
In this article, we will first look at what first-class citizens and higher-order functions are to lay the foundation to explain 'Currying' in JavaScript. The code samples provided along with the explanation should make it easy to follow and understand the concepts.
First-Class Citizens
In JavaScript, the functions are treated as 'First Class' citizens. What this means is that any function can be returned to another function, since a function is fundamentally an object.
Let us take a quick example to explain this better. The below code is an example of a simple function.
In the above example, the number 50 is returned when the function sum() is invoked.
As per the definition of a First-Class citizen, we can return the function sum() instead of the value 50 as shown in the code example below.
Higher-Order Functions
Higher-order functions are functions that take other functions as arguments or functions that return a function as their result.
The below code example will make the above explanation more clear.
Things to note:
- The function 'higherOrderFunction' accepts a function 'func' as a parameter.
- The function 'func' that is passed in as a parameter is referred to as a callback.
Array.forEach, Array.map, Array.filter are some examples of high-order functions.
Currying
Currying a function is the process of taking a single function of multiple arguments and decomposing it into a sequence of functions that each take a single argument.
Let us take the following simple example:
Using ES6 Arrow Functions, the above code can further be written in a simple manner as shown below.
That's all there is to currying. Let us look at a practical use-case of where it can be applied.
A Practical Use-Case
Let us assume we have to read entries from a database of an e-commerce application that has the entities, user, product, and ratings.
To query a single product from the database, we can write a function 'getProductById' as shown below.
By applying the 'currying' concept, we can simplify the above code as shown below.
The advantages of the above approach:
- The above approach obviously simplifies the code by avoiding the calling method to pass the 'connection' object repeatedly.
- Further, the biggest advantage is that we can encapsulate the 'connection' object by modifying the access level to the getProductById() function as private. In simple words, nobody should know about the 'connection' object who is querying for products.
We can further apply the 'currying' concept to the above example and take it to the next level and make it even more generic, so that, you can query for products, users, and reviews table.
Now that we have found a way to generalize querying any table, querying users and reviews are as simple as the code shown below.
As you can see, using the above code simplifies things, promotes reuse, and overall encourages the use of encapsulation.