DEV Community

Danny Tseng
Danny Tseng

Posted on • Updated on

A Qucik Look into JavaScript Closure

Going back to the land of wonderful JavaScript concepts, another interesting concept to discuss in this blog is the concept of "Closure" in JavaScript. It is something that we all have encountered when working with JavaScript but might not have the most solid understanding for.

Closure in simple term is the concept that within nested functions, the inner function has access to the variables and parameters of the outer function. In this case, the inner function essentially has access to the scope of the outer function. A scope pretty much means the visibilities of variables, so the variables of the outer function is visible within the inner function. When creating a function within another function, a scope chain is created. There are three scope chains that are associated with the inner function. The first one is its own scope. The second one is the scope of the outer function. And the third one is the global scope. This is basically what closure is in JavaScript.

Below is a simple demonstration of closure.

Alt Text
The function print is nested inside the outer function printName and when printName is invoked, print is going to get invoked which will log the name that is being passed as a parameter to the outer function to the console. The actual console log is within the inner function which means that name is visible inside the inner function thus validates the concept of closure.

It is possible for the inner function to have more than 3 scope chains. Consider the example below.

Alt Text

In the above code snippet, the most inner function combine can see the variables of the outer function getSentence. Furthermore combine can also see the parameters of the most outer function saySentence. In terms of scope chain, the function combine has four scope chains which are its own scope, the scope of getSentence, the scope of saySentence and then lastly the global scope.

Closure can create unexpected outcomes especially for loops. Before the introduction of the let keyword, var was used for declaring variables. Let's consider the example below.

Alt Text
If you just look at the function, you might expect the results that are getting printed out to be 10, 11, and 12 respectively. However, the results that are printed out are all 13. What is happening here is that the closure which is the anonymous function has access to the outer function’s variables by reference, not by value.

This is because the variable i is declared with var and thus has function scope due to hoisting. The value of i is determined when functions a, b, and c are executed. Because the loop has already run its course by that time, the value of i will be the last value when the for loop ends which is 3 since 3 is equal to the length of the array. Thus the results are being printed out as 13.

There are a couple of ways to solve this issue. One of them as mentioned briefly earlier is to use let instead of var so hoisting of variable declaration is not going to interfere with the result. Inside the for loop, just replace var with let in front of i to produce the right outcome. Another way is to use anonymous closure.

Anonymous closure is a way to create anonymous functions and execute them immediately so the code inside the functions are in a closure where the right values will be captured once these functions are executed. Below is an example of using anonymous closure to capture the i value.

Alt Text
The highlighted code snippet is where the anonymous closure is created. It is also called the immediately invoked function expression(IIFE).

Closure is the concept of creating a function within another function so the inner function gains visibility to the scope of the outer functions. There are different uses for closure and one of them is for managing privacy for variables like the use of anonymous closure. Closure is another example of important concepts that can have surprises in the world of JavaScript. Gaining better understanding of these concepts can greatly decrease the chance of producing unexpected outcomes from our code.


Top comments (0)