closure inside loop

How to use closure inside loop?

In our previous article we have seen introduction about closure . Creating closure inside loops is bit more complicated as it creates undesirable outcomes.

Example:
var funcs = [];
for (var i = 0; i < 3; i++) {
  funcs[i] = function() {
    console.log("i value is " + i);
  };
}

for (var k = 0; k < 3; k++) {
  funcs[k]();
}
Expected Output:

i value is 0

i value is 1

i value is 2

Actual Output:

i value is 3

i value is 3

i value is 3

This problem arises when we use closure inside for loop with var statements.

Var statements are not block scoped. This means when creating a function in first loop we are not creating function with numbers 0,1,2 but with variable i which is just a reference to what is last defined. So in second loop when we log function it will look for value of i and return the last defined value 3 each time it is logged.

You can remove this problem by using let keyword and IIFE(Immediately Invoked Function Expression)

Using let keyword:

You use ES6 let keyword to ensure that the code within for block runs as expected.

const funcs = [];
for (let i = 0; i < 3; i++) {
  funcs[i] = function() {
    console.log("i value is " + i);
  }
}
for (var k = 0; k < 3; k++) {
  funcs[k]();
}
Output:

i value is 0

i value is 1

i value is 2

Using IIFE:

Another way to eliminate the above problem is to use immediately invoked function expression (IIFE), which forces immediate invocation of function as soon as the loop runs. Instead of stacking and waiting for the loop to finish the function runs as soon as the loop starts. This will result in our expected output.

const func = [];
for (var i = 0; i < 3; i++) {
  func[i] = (function(value) {
    console.log("i value is " + i);
  })(i);
}
Output:

i value is 0

i value is 1

i value is 2