Closures in JavaScript

A wise man once said
“You need to master the closure to be a Guru in JavaScript”.

Once upon a time there was an crazy architect who decided to build an underground hotel. He developed that hotel with 2 underground floors namely Basement 1 (B1) & Basement 2 (B2). Every floor has two rooms, one room for staying and another for some fun activity.
On ground floor, there is hotel reception and cafeteria. On level B1, there is table tennis room. On level B2, there is snooker table room.
There is a lift which operates using access card only. There is one interesting rule of this hotel which cannot be broken under any circumstances. Rule is that you can access.
- Ground floor (reception and cafeteria).
- Floor you booked and
- Any fun activity room till your floor.
Once floor B1 was booked by Jon Snow and floor B2 was booked by Khaleesi. By rule, anyone can access full ground floor. Jon can access Table Tennis room but cannot access Snooker table room. Khaleesi can access Table Tennis room as well as Snooker table room.
On ground floor while dining, Khaleesi asked Jon about JavaScript closure. As usual Jon didn’t know that. He asked, what is closure in JavaScript? Khaleesi then starts explaining.
“Short answer is, it’s just an inner function. But actually it is a lot more than just inner function.”
Closure Basics
1. Access variables of different scopes.
Our hotel works like closure. Khaleesi can access ground floor, table tennis room and her floor. Similarly in closure, we can access local scope, outer scope and global scope.
2. Access variables after execution.
In case of some other languages, when a function is executed, all its local variables are not accessible. But in case of JavaScript closure, even though function has executed, it still holds references of its local variables.
In example above calculateSalary()
is the closure. When line 10
is executed, getSalary()
is called and value of baseSalary
is considered as 100. This function call return the inner function definition(closure). That function definition is assigned to variable monthlySalary
. At this moment the closure is not yet executed.
When line 11
is executed, closure gets executed. This closure (inner function) has access to local variables like hraAmount
, outer scope variables like transportAmount
, global variables like sodexoAmount
.
3. private methods
There are no private methods in JavaScript but we can achieve that effect using Closure. In this case calculateSalary
is a private method.
4. Native Examples of Closure
- setTimeout
The function part of setTimeout
is nothing but a closure. It gets executed after time specified.
- setInterval
Similar to setTimeout
, the function part of setInterval
is a closure. It get executed every time when specified interval has completed.
- Event Listener Functions
Every event listener function in JavaScript is a closure. In example above addUser
function is a closure.
- http API callback functions
http API can have multiple callback functions. Every API callback function in JavaScript is a closure.
5. Closure inside loop — Anonymous Closure
Before ES6
, when we use closure inside any loop, we have to be extra careful. While iterating in any loop, wrong counter will get mapped to closure if we do not take care. It can create bugs in our program. There are multiple ways to resolve this problem. Whenever we use closure inside a loop, I recommend to cover that closure with an anonymous closure and pass the counter to anonymous closure.
6. Cons of Closures
- When there is too much nesting of closures, it becomes very hard to understand the code.
- When there is too much nesting of closures, it becomes a nightmare to debug an issue inside such closures.
- If we create closures unnecessarily, it can cause performance issues.
Conclusion:
Closure is very interesting and highly used concept of JavaScript. But we need to be extra careful while using it.