Closure in JavaScript

Challenge Inside! : Find out where you stand! Try quiz, solve problems & win rewards!

Video Tutorial

Closures in JavaScript

Overview

A Closure can be defined as the bundle of functions along with its lexical environment. Closures are created every time when a function is created. To make it more intuitive and easy to remember, we can say that every function in Javascript remembers its origin.

Scope of Article

  • In this article, we will go through everything you need to know about the closure in JavaScript starting from scopes, lexical scopes, closures, scope chain, dynamic scopes, and static scopes, closures in the loop, use of closure in JavaScript, and some tricky and insightful examples. So fasten your seatbelts and get ready for this insightful journey.

What are Scopes?

Scopes in JavaScript are the portion of the code where the variable is accessible. Let us walk through some examples:

When we look at the above examples, we see that we had no issues accessing "name" but accessing "superhero" was not possible. Why? The reason for this is "superhero" was declared inside the "scope" of the if statement. So, this defines the definition of scope which we discussed earlier. In Javascript we have different types of scopes, some of which are:

  1. Block Scope
  2. Global Scope
  3. Functional Scope.

Types of Scopes

Let us understand them briefly.

Block Scope

With the introduction of let and const keywords, variables can be scoped to the nearest block of code or pair of curly braces "{}". Just for your information, var is not block scoped.

Global Scope

As the name suggests, the variable which is accessible from everywhere in the program is said to exist in the global scope.

Ex:

Here the variable name is accessible inside the main Function as well outside it. The name can be accessed from anywhere in the code. So the name exists in the global scope.

Function Scope or Local Scope

When a variable is declared inside the function, it can only be accessed from within that function. This means that this variable exists in the functional scope and cannot be used outside this scope.

Ex:

But the most important scope in terms of understanding closures is Lexical Scope. But before jumping directly to Lexical Scopes we should have some knowledge regarding Scopes Nesting.

Scopes Nesting

Let us go through this block of code:

Here we have multiple variables defined in multiple nested scopes and this code runs perfectly fine. So we can easily conclude from here that the variable from the outer scope is accessible to the inner scope. Let us move a step ahead and take examples including functions:

Here, name is accessible to the newFunction and when newFunction is called, it logs the name.

Lexical Scopes

In the example, we saw that the variable of the outer scope is easily accessible to the inner scope. This is possible because of lexical scoping. In the above example, the lexical scope of newFunction consists of the lexical scope of demoFunction and the global scope. In easy terms, lexical scoping means that inside an inner scope, you can use the variable of the outer scope. It is called lexical scope as the engine determines the scopes during the lexing time.

Closure in JavaScript

Now we have the background knowledge to understand closures. If we check the definition of closures on MDN, it says:

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment).

As we know what lexical scoping is, this definition is explanatory. But we will define Closure in JavaScript as simply as possible.

Uses of Closure

Let us take a code snippet:

Here, we have an outerFunction, which has an innerFunction. This innerFunction is manipulating the initial which is defined in its outer scope. Now when we call outerFunction, it returns innerFunction, and when we try to call innerFunction, we see that it still has access to an initial, though the function is called outside the scope of outerFunction. This is possible because of closures. Because of closures, functions in Javascript can close over the value of their outer scope and remember them. So no matter from which scope they are called, they can easily access the variables in their outer scope.

So a sweet, simple, and intuitive definition of closure can be:

"A closure in JavaScript is a function that remembers its outer variables and can access them even when called independently."

Scope Chain

In Javascript, we know that a scope has access to its parent's scope or outer environment, which in turn has access to its outer environment. This can be represented as a hierarchical chain scope and this is called Scope chain.

Closure and Scope Chain

Now that we have the knowledge of the scope, scope chains, and closures let us see how scope chaining and closures are related to each other. By scope chaining, we know that Javascript will keep looking for the variable in its scope as well as its parent scope till it reaches the global scope. The same is the case with closures. Let us have a look at it by an example.

Here we can simply predict that the output is AryanInnerInnerInner. Now suppose we comment out the line where we are assigning AryanInnerInnerInner to name.

Now the output is 'AryanInnerInner'. Again if you comment out the line where 'AryanInnerInner' is assigned to the name, you will get output as 'AryanInner' and if you do the same with 'AryanInner' , you will get 'Aryan' and finally, if you comment out 'Aryan', you will get ReferenceError.

You must have guessed till now what is happening. Javascript is searching for the variable name. The search begins from the local scope (where name is 'AryanInnerInnerInner') and if the variable is found, Javascript stops searching and returns which is exactly what happened when we ran the code for the first time, but if no variable is found Javascript looks in the parent's scope for name (in this case 'AryanInnerInner') and then parent's parent (in this case 'AryanInner') and finally the global content (in this case 'Aryan'). If the variable is not present in the global scope, ReferenceError is raised.

The scope chain or bundling of the outer environment with the function happens at the time of the function's creation. In simple words, the outer environment of the function is defined statically by location within the source code.

Here we have frequently used the term static scopes. So let us take a moment and understand the difference between static scope and dynamic scope.

When to Use Closure in JavaScript?

Closures are used every time and hence it becomes difficult to pinpoint the use cases of closures. If you have read the article till here many of the problems solved by closures should be known to you. But if I go through them again, some use cases of closures that we have already discussed are:

  1. The for-loop dilemma
  2. Emulating private variables in Javascript.
  3. Creation of Higher order functions

But still, there are some advanced use cases of closure in JavaScript that I haven't discussed yet, let us go through them as well.

  • Currying: Currying is the pattern of functions that immediately evaluate and return other functions. This is made possible by the fact that Javascript functions are expressions that can return other functions. Curried functions are constructed by chaining closures by defining and immediately returning their inner functions simultaneously. It is a very powerful technique and is frequently asked. Example:

Here the variable a and b are accessible to the innermost function because of closures.

  • Function Composition: Function composition is the ability to create functions from other functions. It is a very powerful feature and can reduce the redundancy in our code to great extent.

Example:

Some Examples of Closure in JavaScript

Though we have covered a lot of code snippets along the way, still we will go through some of the famous closure examples which will solidify your understanding even further.

Example 1:

What would be the output? The code looks overwhelming at first but if we break it down, we can easily see what this code is doing and how closures are involved in this. So, we have a function by which takes params as an argument and then returns another function that takes a and b as arguments and returns the difference between a[propname] and b[propName].

Then we have some values initialization and then we are calling this by function as a comparator in sort function. So in the by function, because of closures, propName is available to the inner function, and hence the difference between the heights is returned.

Example 2

Try yourself and predict the output.

Here, the value of a and b are inside the outer function and we have created two instances of the outer function i.e. X and Y. So any change which we make in the scope of X would have an effect on the scope of Y.

Example 3

This snippet is very similar to the problem which we did in the closure in loops section. Try predicting the output in both cases and also try to implement the solution using the let keyword.

These examples are sufficient for testing and revising the concepts of closure in JavaScript.

Static and Dynamic Scopes

In static scope, variables are referenced in a context at the time of creation. Whereas in dynamic scope, variables are referenced at the run time. I know this won't make much sense but let me explain this with the help of an example.

Note: If you run the code snippet which is used as an example, you will only get the output for the static scopes as Javascript use static scope. Dynamic scope outputs are just for reference and is explained in detail below.

Let us walk through the code one by one and try to understand what is happening. For the firstFunction, it will return 7 in both types of scopes. But for the secondFunction, if we have the static scope, it will return 7 and for the dynamic scope, it will return 11. The reason is, in the case of static scoping, the value of first is determined at the time of function creation which is 2. So the output is 7. But in the case of dynamic scoping, the value of first is determined at the runtime. When secondFunction is called, the value of first inside its scope is 6, so the output would be 11.

Most of the modern day languages use static scope. Perl uses a both static and dynamic scope.

Difference between Static and Dynamic Scope

Static ScopeDynamic Scope
In static scoping, variable always refers from top level enviroment.In dynamic scoping, variable is searched first in the current block and then its caller function.
Most of the programming languages uses static scoping.Very few languages uses dynamic scoping.
It is more developer friendly.Not much developer friendly.
Examples of languages using static scope: JS, C++, C etc.Languages using Dynamic scoping: Perl.

Emulating Private Methods with Closure in JavaScript

In Javascript, we don't have an out-of-the-box way to create a private variable as we have in other languages like JAVA, C++, etc. For your information, private variables are the variables that are visible only to the class to which they belong and cannot be accessed/modified directly from outside. But we can use closures to emulate this behavior and create a basic factory function with a private variable and setter and getter function.

Factory Function is nothing but a function that returns an object. These are different from class and constructor as they don't require new keyword for instantiation.

Here we have created a simple Factory Function Friend (kinda class) with a private variable _name (a good practice to have _ in front of a private variable), getter function getName, and setter function setName. When we try to access _name directly, it returns us undefined as it is in the function scope and cannot be accessed from outside. So using closures we can emulate private variables.

JavaScript Closures in a Loop

Now we have somewhat in-depth knowledge of closures and it is time to go through some of the advanced use cases of closure in JavaScript. We are going to discuss one of the very famous JavaScript questions, which is:

Predict the output of the following code snippet:

Here someone not familiar with Javascript will answer 0,1,2,3,4 where each number is printed at an interval of 1 sec. But its correct answer would be 5,5,5,5,5 But why? Let us demystify this code.

Firstly, we have used var in front of i and secondly, a setTimeout function is called. Now because setTimeout function calls the function after 1 second, by the time 1 sec passes, the loop has completed its iteration and the value of i is 5. As i is of var type, its value remains the same (var not blocking scoped). So when the callback function is called, i is 5 and hence we get 5,5,5,5,5 as output.

Now how to fix this? How can we achieve 0,1,2,3,4 as output? So, I will tell you two ways of doing this.

Using IIFE AND CLOSURES

The bottleneck in the above approach was the value of i being global 5 for each callback function call. If we can somehow remove this, our problem would be solved. So, we create a new scope for i in each iteration. In this way, each function call would have its own value of i and we get the desired output.

In the above code, we just wrapped the setTimeout function inside an IIFE, so now for each callback function (function inside the setTimeout) the value of i will not be the value of the iterator but the value of i in the outer function. Since this function is called for each value of i it will log all the value of i as desired.

Using let keyword in ES6

A very simple solution to this can be to use let instead of var in front of i. let creates a new lexical scope in each iteration which means that we will have a new i in each iteration. The reason, as we discussed above is let is block scoped.

One of the easy ways to understand this is when we use var, we have only one instance of i and at each iteration, its value is changing. But when we use let, for each iteration a new instance of i is created with a different value. Hence we get the desired result.

Conclusion

Closure in JavaScript is something that is used by everyone but still, most of the developers are not familiar with it and it is completely fine. Closures are hard to get your head around and you will become better and better with time. So to wrap up this article, let us go through the important points we discussed in this article:

  • A closure in JavaScript is a feature where an inner function has access to the outer (enclosing) function’s variables — a scope chain.

  • Closures in Javascript are created along with the function.

  • Lexical scoping is the environment that holds the variables of the current scope as well as the outer scope.

  • As each scope in Javascript has access to its parent's scope or outer environment, we can nest these scopes in hierarchical order called scope chaining.

  • Each closure has three scopes namely global scope, function scope or local scope, and block scope.

  • In languages using static scopes, variables are referenced at the time of creation whereas, in dynamic scoping, variables are referenced at run time.

  • With the help of closures, we can solve the for loop dilemma in Javascript.

  • Closure in Javascript finds its uses every time a function is created. Some common use cases are Higher Order Functions, Currying, and Function decomposition.