DEV Community

Cover image for The concept of Triple CCC: Currying, Closure, Callback in JavaScript
Rahul Banerjee
Rahul Banerjee

Posted on

The concept of Triple CCC: Currying, Closure, Callback in JavaScript

JavaScript is a programming language that is used in both FrontEnd and BackEnd to build interactive web applications. It is the only scripted language that the browser can understand. As far today, almost 98% of websites use this language on the client-side for web page behavior. It is the most popular programming language in the world.

But the journey of this language was not so smooth. This language was designed by Brendan Eich and first appeared on December 4, 1995. At the initial moment, it was only used to bring interactivity to the web pages while the HTML and CSS are used to structure and design the web page.

The Game-changing moment happens when Ryan Dahl introduces NodeJS for the first time in 2010. It is nothing but an open-source, cross-platform, back-end JavaScript runtime environment that runs on the V8 engine and executes JavaScript code outside a web browser.

Since that moment this language has been used widely. In 2022, it is worth learning this amazing language to build a strong career in the Web Development sector. To make your learning journey smooth and also make your base solid, today, I will discuss the concepts of JavaScript those are Currying, Closure, and Callback (CCC).

No matter which position you are in now! If you want to make yourself a good JavaScript developer then you need to have a solid understanding of these topics. Moreover, it will help you to crack interview questions because most of the time there’s a common question that interviewers ask about these topics. At the end of this tutorial, you will get a clear understanding of Currying, Closure, and Callback in JavaScript.

Things You will learn from this tutorial

We will cover the following topics in this tutorial:

  • Function as First-Class Citizen
  • Currying
  • Closure
  • Callback

Function as First-Class Citizen

Before learning about the CCC’s concepts, you need to understand the concept of a First-Class Citizen. In JavaScript, a function is said to be a First-Class Citizen for the following three reasons

  • A function can be assigned as a value to a variable
  • A function can be passed as an argument to other functions
  • A function can be returned by another function

Let's take a look at some code snippets that show how a function in JavaScript can satisfy the above three reasons

A function can be assigned as a value to a variable

const myFunc = name => `Hello, ${name}! `;

const result = myFunc("Rahul");
console.log(result);

// Output: Hello, Rahul!
Enter fullscreen mode Exit fullscreen mode

Here, you can see that we have declared an arrow function and later on, we have stored it into a variable named myFunc.

A function can be passed as an argument to other functions

const myFunc = (greetings,name) => `${greetings()}, ${name}! `;

const hello = () => "Hello"
const bonjour = () => "Bonjour"
const salut = () => "Salut"

const result_1 = myFunc(hello,"Rahul");
const result_2 = myFunc(bonjour,"Rahul");
const result_3 = myFunc(salut,"Rahul");

console.log(result_1);
console.log(result_2);
console.log(result_3);

// Output: 
// Hello, Rahul! 
// Bonjour, Rahul! 
// Salut, Rahul! 
Enter fullscreen mode Exit fullscreen mode

Instead of hard-coding "Hello" in our function myFunc, we now accept a parameter which is a function. As you can see, there are three different functions hello,bonjour and salut and each of them are passed as an argument to myFunc

A function can be returned by another function

const outerFunc = () => {
  console.log("Outer Function")
  const innerFunc = () =>{
    console.log("Inner Function")
  }
  return innerFunc
}


outerFunc()()
// OUTPUT
// Outer Function
// Inner Function


const myFunc = outerFunc()
myFunc()
myFunc()
// OUTPUT
// Outer Function
// Inner Function
// Inner Function
Enter fullscreen mode Exit fullscreen mode

We have a function named outerFunc. It doesn't do much, it simply prints a statement to the console. Another function called innerFunc is created inside. The innerFunc also doesn't do much, it simply prints a statement to the console. The outerFunc returns the innerFunc.

There are a couple of ways this can be used. The first way is to use two braces together. The first pair of brackets invokes outerFunc and the second pair of brackets invokes the object returned by outerFunc, i.e the function innerFunc.

In the second way, we store the returned function in a variable and invoke it it like a normal function

Currying

In simple terms, Currying is a technique of chaining multiple functions. It’s a functional programming feature. Let’s understand this concept by solving a common interview question :

The Question

Look at the below code snippet.

function sum(x, y, z){
    return x + y + z
}

console.log(sum(10, 20, 30))

// Output: 60
Enter fullscreen mode Exit fullscreen mode

The task you need to perform is to call the sum function like sum(10)(20)(30) instead of sum(10, 20, 30) this.

// Current way of Invoking function
sum(10, 20, 30)

// Desired way of Invoking function
sum(10)(20)(30)
Enter fullscreen mode Exit fullscreen mode

How can you perform this action? The answer is simple, the term you need to use is Currying. See the below code example

function sum(x){
    return function(y){
        return function(z){
            return x + y + z
        }
    }
}

console.log(sum(10)(20)(30))

// Output: 60
Enter fullscreen mode Exit fullscreen mode

Here, you can see that we have declared a function inside another and these have created a function chaining. You can also see we are getting exactly the same output and this process is known as Currying in JavaScript.

Currying is used in popular javascript libraries such as Lodash and Rambda

Closure

A closure in JavaScript is nothing but a function that references variables in the outer scope from its inner scope. Let’s see the problem that closure solves in the below section and by doing so, you will be able to know why we need

function sayHello(){
    let name = 'Rahul'

    function inner(){
        console.log(`Hello ${name}`)
    }

    return inner
}

let abc = sayHello()
console.log(abc)

// Output: 
// [Function: inner]
// Hello Rahul
Enter fullscreen mode Exit fullscreen mode

Here, you can see that we are getting the output as expected. But the main question is how we are getting this? Let’s break it down in the below section:

At first, we declared a function named sayHello() and stored a string inside the name variable. Later on, we declared another function and print the name with a Hello message, and returned the inner() function. Finally, we have stored the returned function into the abc variable.

Now, when JavaScript will execute the code it will not find the name variable as the sayHello() function’s memory has been destroyed. But how we are getting the output as expected?

The main reason behind this is that Closure. Here, it is true that the sayHello() function’s memory has been destroyed but it creates a reference of that function and as a result, while executing the inner() it can access the variable from the reference of the sayHello() function. To perform this action, you don’t need to write one line of extra code. Because the JavaScript engine is smart enough to perform this action. All you need to do is to understand the concept of closure and it is created by default every time when a function has been created in JavaScript.

Callback

A callback is a function passed as an argument to another function. Let's look at a use case below.

Suppose, we have an array of names saved in our database. We want to add a new name and later on, we want to print the names with the newly added name. To perform this action we have written the below code:

let names = ['Rahul','Rohit','Rohan']

function addNewName(name){
    setTimeout(function(){
        names.push(name)
    },5000)
}

function printNames(){
    setTimeout(function(){
        console.log(names)
    },3000)
}

addNewName('Alex')
printNames()

// Output:
// [ 'Rahul', 'Rohit', 'Rohan' ]
Enter fullscreen mode Exit fullscreen mode

Here, you can see that, we have added the functionality for adding new names but in the output, the new name has not been added. The main reason behind this is the asynchronous behavior of JavaScript. We know that for tasks that take much time, JavaScript does not wait for them, rather they work on other lighter tasks and keep the heavy task in the queue. The same things happen here.

We need to use a callback function so that we can break the asynchronous behavior of JavaScript and it can wait for us based on a specific task. See the below code example to understand it more clearly:

let names = ['Rahul','Rohit','Rohan']

function addNewName(name, cb){
    setTimeout(function(){
        names.push(name)
        cb()
    },5000)
}

function printNames(){
    setTimeout(function(){
        console.log(names)
    },3000)
}

addNewName('Alex',printNames)

// Output:
// [ 'Rahul', 'Rohit', 'Rohan', 'Alex' ]
Enter fullscreen mode Exit fullscreen mode

We have passed a function (printNames) as an argument to another function (addNewName). This time printNames will execute only after the previous functions have been executed. This concept is known as the Callback and you can see that we have called this function after the previous function finished its tasks. That’s the reason we have mentioned Callback as Call later.

There are many advanced concepts that have been built on top of the Callback. You may also have heard about the concept of Callback hell. I'll be discussing this in one of the future articles.

Conclusion

In this tutorial, we have covered three essential concepts of JavaScript (Currying, Closure, and Callback). I hope you found this article helpful and informative.


This article was originally posted on 
https://realjavascriptproject.com/javascript-currying-closure-callback/

Connect with me on LinkedIn: 
https://www.linkedin.com/in/rahulbanerjee2699/
Enter fullscreen mode Exit fullscreen mode

Discussion (3)

Collapse
jonrandy profile image
Jon Randy • Edited on

A much nicer way to write your curried sum function:

const sum = x => y => z => x+y+z
Enter fullscreen mode Exit fullscreen mode
Collapse
rahulbanerjee99 profile image
Rahul Banerjee Author

oh I didn't know this, thanks for sharing!

Collapse
aishanipach profile image
Aishanii

V helpful, thanks