4 daily use-cases of first-class functions in JavaScript
Tags: javascript, node, programming, webdev
Published: 2021-12-22 07:10:35

Every language has features that make it special. In this article, I want to mention the “first-class function” characteristic in JavaScript. The article isn’t a tutorial about how to use it. Instead, I would like to point out some real-life usages of the feature and the benefits it brings to developers. Let’s start!

#### What is “first-class function” about?

The definition from [Wikipedia](https://en.wikipedia.org/wiki/First-class_function):

_In computer science, a programming language is said to have_ **_first-class functions_** _if it treats functions as first-class citizens. This means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures._

For example, in JavaScript, we can assign a function to a variable.

{% gist https://gist.github.com/ddkhoa12c3/3528242a5ae8c4376aa022c798135fe8 file=assign-function-to-variable.js %}

The definition is a bit confusing if we are reading it for the first time. However, the fact is that we used it even without knowing about it.

#### AddEventListener — The first lesson when learning JavaScript

Back in the past, JavaScript was introduced to add dynamic behaviors to a website. For instance, we want to change the text when the user clicks on the button. Here comes the very first line of code when someone learns JavaScript.

{% gist https://gist.github.com/ddkhoa12c3/0e6834fc0d8039f97ab39e70e851a354 file=add-event-listener.html %}

In line 9, we passed the function as an argument to the method addEventListener. The function is associated with the event “click” of the button. When the event is fired, the function will run.

**Let’s be curious — Part 1**

To understand the role of the feature, let’s think about languages where it isn’t available. Adding dynamic behaviors is something **common** in UI development, regardless of the programming language. _What if we cannot pass the function as an argument?_ I am looking forward to your response in the comment section.

#### Sending HTTP requests — The common task in JavaScript

I will take [Axios](https://github.com/axios/axios) as an example. It is one of the most popular JavaScript libraries to send HTTP requests. In a project, we might need to add some common configurations. For example, to send the JWT to the server, we want to add the header Authorization to all requests. So, we need a function to grab the JWT somewhere and add it to the header. It could be done using interceptors.

{% gist https://gist.github.com/ddkhoa12c3/6f46ef61cd72cde147fcdd5106690be0 file=axios-interceptor-example.js %}

Again, we pass 2 functions as arguments of the `use` method. The first function sets the token in the request’s header. The second function runs if there is an error (we don’t define it here for simplicity). When Axios processes a request, it will run all interceptors one by one to transform the user’s config to the full configuration. Then it will send the request to the server.

The way Axios processes interceptors is a nice illustration of first-class function in JavaScript.

{% gist https://gist.github.com/ddkhoa12c3/5e6cb1829a41ca2d618fb4eac939e7f2 file=axios-interceptor.js %}

In line 23, the fulfilled and rejected functions we pass in the `use`method are added to the _requestInterceptorChain_. We store functions in an array. Then Axios will run each of them. Inside the while loop, you can see functions are assigned to variables to be called.


![How Axios handles 1 request. Interceptors are functions that are stored in 2 arrays.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4cd9qlqprmhz6u4an7wc.png)

**Let’s be curious — Part 2**

Sending HTTP requests is not limited to frontend development. When developing the backend part, we might need to send requests to an external server. Could you explain to our community how HTTP request configurations are processed in your preferred language?

#### Handling HTTP requests in Node.js

With Node.js, we can develop the backend part using JavaScript. Backend development is about handling HTTP requests, that is: to receive them, parse them, find the correct answers, and respond to clients. [One of the most used frameworks of Node.js is Express.js](https://www.toptal.com/nodejs/nodejs-frameworks-comparison). This framework uses _middleware_ to do the tasks mentioned above. Here is the definition of middleware from [Express official page](https://expressjs.com/en/guide/using-middleware.html):

**_Middleware_** _functions are functions that have access to the request object (`req`), the response object (`res`), and the next middleware function in the application’s request-response cycle._

You can see the example of middleware below.

{% gist https://gist.github.com/ddkhoa12c3/6a28b74598290bb3aafda3c2e83c3e37 file=express-middleware-example.js %}

The middleware function is passed in the `use` method. It, in turn, accepts another function `next` as an argument. The `next` function is called at the end to pass the control to the following middleware in the stack.

Express is popular and widely used for its _simplicity_. “[An Express application is essentially a series of middleware function calls.](https://expressjs.com/en/guide/using-middleware.html)” Despite the trivial looks, Express’s middleware can help us do all tasks of a web server: logging the request, compressing the response, setting cookies, preventing XSS attacks … just to mention a few.


![Schema of a simple Express application.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56dpkxm0k5mqwidpnz2x.png)

**Let’s be curious, again!**

How HTTP requests are processed in other backend frameworks? Can you compare it to Express middleware? What are the advantages/disadvantages of each method? You see, there are a lot of questions to study!

#### Last but not least — Callback hell in JavaScript

As you know, JavaScript is single-threaded. But it provides an effective mechanism to deal with long-running tasks. Instead of waiting for the task to be finished, we can immediately start the next one, and define what we need to do when the former task has been accomplished. It’s where callback functions come from — to define what should be run after a long-running task.

{% gist https://gist.github.com/ddkhoa12c3/c55d706b1f1e37c40cb545551e12a218 file=callback-example-node.js %}

Callback functions give us a powerful tool to deal with I/O bound applications. However, every good thing can go bad if it is abused. You can see the example below.

{% gist https://gist.github.com/ddkhoa12c3/eaade331dd6a4184dcb66822cd497118 file=callback-hell-example.js %}

Multiple callback functions and if/else statements make the code hard to understand. It can become unmaintainable in the future if we add more logic. Because of this problem, newer features are introduced. [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) appeared to help us write a cleaner program. [Async/await](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await) keyword allows us to write asynchronous code that looks like synchronous code.

#### Wrap up

In the article, I showed you some real-life examples of using “first-class function” in JavaScript. We use this feature daily and take it for granted. Through the examples, I hope you can see some cool things that the peculiarity offers to us. I left many questions for you as well. Curiosity is one of the characteristics that help us grow up. I will be glad to see your answer in the comment section so that we can learn from each other. You can also share the article with developers in other languages to discuss. Thank you for reading!

#### Resources

*   [https://en.wikipedia.org/wiki/First-class\_function](https://en.wikipedia.org/wiki/First-class_function)
*   [https://github.com/axios/axios](https://github.com/axios/axios)
*   [https://www.toptal.com/nodejs/nodejs-frameworks-comparison](https://www.toptal.com/nodejs/nodejs-frameworks-comparison)
*   [https://expressjs.com](https://expressjs.com)
*   [https://nodejs.org/api/fs.html#fsreadfilepath-options-callback](https://nodejs.org/api/fs.html#fsreadfilepath-options-callback)
*   [http://callbackhell.com/](http://callbackhell.com/)
*   [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
*   [https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async\_await](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await)