Closure is basically an inner function which has access to variable of outer function.
Lets see an example:
function outer() {
var a = 123;
function inner() { // this function act as closure
console.log(a);
}
inner();
}
outer(); // it will print '123'
The amazing thing is, even if the outer function returns the inner function then also inner function will have access to outer function variables, in other programming languages if a function returns then it becomes ready for garbage collection or is completely removed from the heap, but in Javascript if there is closure then the parent function variables remain in the heap.
So the following code is also correct...
function outer1() {
var a = 123;
return function() { // this function act as closure
console.log(a);
}
}
var func = outer1();
func() // this will also print '123'
Advantages of closures:
- Callbacks implementation in javascript is heavily dependent on how closures work
- Mostly used in Encapsulation of the code
- Also used in creating API calling wrapper methods
Disadvantages of closures:
- Variables used by closure will not be garbage collected
- Memory snapshot of the application will be increased if closures are not used properly
Lets solve a famous interview problem based on closures
When you are performing an async operation inside a loop in javascript make sure each iteration has its own respective value passed to the operation.
Lets see this question.
What will be the output of the following?
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log('Index: ' + i + ', element: ' + arr[i]);
}, 3000);
}
Surprisingly the output will be Index: 4, element: undefined(printed 4 times)
This happens because until the loop is executed completely the function inside setTimeout
will not be called since it is async function, after the loop is executed functions stacked inside setTimeout
will start invoking and will try to print the value of i
which will be 4 by then, so how to print the correct value of i
with out removing setTimeout
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
(function(i) {
setTimeout(function() {
console.log('Index: ' + i + ', element: ' + arr[i]);
}, 3000);
})(i)
}
There are lot of problems solved by closures and some are created by closures, make sure to use closures wisely
Feel free to add you thoughts in the comments
Follow me for more such content
Top comments (3)
Not all closures remain in the heap. The first two examples you show allude to normal stack frame run. It doesn't "remain" in the heap.
The closure can outlive the stack frame, especially if you have async functions that are referencing variables in the parent function.
Hey Vishal. That's a very good explanation of closure.
We can also do this by changing var to let