DEV Community

Cover image for Closures in Javascript
Vishal Gupta
Vishal Gupta

Posted on

Closures in Javascript

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:

  1. Callbacks implementation in javascript is heavily dependent on how closures work
  2. Mostly used in Encapsulation of the code
  3. Also used in creating API calling wrapper methods

Disadvantages of closures:

  1. Variables used by closure will not be garbage collected
  2. 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)

Collapse
 
nullspace profile image
null • Edited

if there is closure then the parent function variables remain in the heap

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.

Collapse
 
arvindsridharan profile image
arvindsridharan

Hey Vishal. That's a very good explanation of closure.

Collapse
 
venomfate619 profile image
Syed Aman Ali

We can also do this by changing var to let