In this article, we are going to talk about closures in JavaScript. I'll walk you through the definition of a closure, a simple day-to-day fetch utility closure example, and some of the advantages and disadvantages of using closures. Show Table of Contents
Without further ado, let's get started. PrerequisitesYou should have a good understanding of the following topics to understand this article:
What are closures?Closures are functions that have access to the variables that are present in their scope chain even if the outer function ceases to exist. To understand this in more detail, let's understand what a scope chain is. Scope chain refers to the fact that parent scope does not have access to the variables inside its children's scope, but the children's scope does have access to the variables present in its parent scopes. Let's make this clearer by taking a look at an example below:
As you can see, we have a function called 0. This function accepts 1 as an argument. Let's consider the 0 function as our parent function.We have another function that has been defined inside the parent function, that is 3. This function will accept 4 and 5 as an argument and return an object that constitutes a variable 1 that is present outside its scope.But a question arises as to how the inner function resolves the variables that are present in the parent scope. Well, this is possible via lexical scoping. Using lexical scoping, the JS parser knows how to resolve variables present in its current scope or in fact knows how to resolve variables present in the nested functions. So based on the above explanation, 3 will have access to the variables present in its outer function 0.In the above example, the inner function 3 is a closure. To understand closures in detail we will first go through the characteristics of closures which are as follows:
Let's get into more detail on each of these points. Even if the outer function ceases to exist, it still has access to its parent variables.This is the basic functionality of any closure. This is their main life motto aka their working principle. To see this in action we will now execute the above 0 function.
Calling the 0 function will return us another function that is our closure.Now let's execute this closure:
Once the closure is executed, it returns the following object:
Here again a question arises: How does the 3 function have access to the variable 1 that was not present inside it?If we go through the definition of closures, and scope chaining that we discussed earlier, it perfectly fits into that instance. Let's dig deeper into why closures still have access to the variables that are defined outside their scope, even if the outer function ceases to exists – for example, 1? The answer is simple: closures do not store static values. Instead, they store references to the variables present inside the scope chain. In this way, even if the outer function dies, the inner function, that is a closure, still has access to its parent variables. Use case of closure: Creating a fetch utility with closuresNow that we've learned what closures are, we will create a nice general purpose utility function. It will handle different request methods such as GET and POST with REST APIs. For this use case,
Let's first discuss why we even need to design such a utility. There are couple of reasons:
Let's dive into the details of this utility. Our fetch utility will look like below:
Now let's see this function in action. Call our 6 function to initialize the 7: Initializing the baseURL
Executing the closureAs you can see this returns us an array of fetch API instance and the request body that we configured. Finally, we can make use of the 0 fetch API to call the request 1 like below:
We can also create a POST request similar to the above GET request. We just need to call the 7 again as below:
And to execute this post request we can do the similar operation that we did for the GET request:
If we closely look at the above example, we can see that the inner function 9 has access to the variables present in its scope chain. With the help of lexical scoping, during its definition of 9 it resolves the variable names.In this way the closure references the variables 7 and 8 during its definition even after the outer function 6 has ceased to exist.If we think of closures from a different perspective, then closures help us to maintain a state like 7 and 8 that we can use across function calls.Advantages of closuresHere are some advantages of closures:
Disadvantages of closuresThere are two main disadvantages of overusing closures:
SummarySo in this way closures can be really useful if you want to deal with or implement certain design patterns. They also help you write neat and modular code. If you liked the idea of closures, then I would recommend reading further on the following topics:
Thank you for reading! Follow me on Twitter, GitHub, and LinkedIn. ADVERTISEMENT ADVERTISEMENT ADVERTISEMENT ADVERTISEMENT ADVERTISEMENT ADVERTISEMENT ADVERTISEMENT Front-end developer👨💻; Book enthusiasts📖 If you read this far, tweet to the author to show them you care. Tweet a thanks Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started |