1

We have the following examples that I'm trying to understand:

function makeFunctionArray(){
   const arr=[];
   
   for(var i=0;i<5;i++){
      arr.push(function(){console.log(i)})
   }  
   
   return arr;
}
const functionArr = makeFunctionArray();
functionArr[0]();


function makeFunctionArray2(){
   const arr=[];
   
   for(let i=0;i<5;i++){
      arr.push(function(){console.log(i)})
   } 
   
   return arr;
}
const functionArr2 = makeFunctionArray2();
functionArr2[0]();

In the first function i is declared with var so has scope of the function. When we return arr each function() in the array is evaluated with i = 5 when the function is executed.

In the second function i is declared with let so the scope of i is now just the for loop. When arr is returned we have an array[0] - arr[4] which each says function(){console.log(i)}. since i is no longer defined when we return arr how is it being evaluated?

DCR
  • 14,737
  • 12
  • 52
  • 115
  • https://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue – epascarello Feb 26 '18 at 18:06
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var – Teemu Feb 26 '18 at 18:07
  • neither of those references explains the confusion caused by declaring i with let. Outside the for loop i doesn't exist, how then is console.log(i) being evaluated? – DCR Feb 26 '18 at 18:11
  • Because that's what 'closure' *means*: the function (in this case a lambda with the `console.log` *closes over* the surrounding scope at the time of it's creation. In both examples it closes over `i`. Only difference is the way `i` is scoped. In the first `i` is scoped to your function and is successively mutated, in the other it is bound to the value of `i` at the time the function is created. – Jared Smith Feb 26 '18 at 18:11
  • so the function doesn't close until i closes? – DCR Feb 26 '18 at 18:13
  • You keep saying that `i` doesn't exist, or that `i` is no longer defined. But it is: the closure captures it. I don't know what it means for a variable or function to 'close'. What does happen is that rather than be garbage-collected `i` is captured by the inner function so the reference is maintained. – Jared Smith Feb 26 '18 at 18:13
  • outside the for loop in the second example console.log(i) is undefined, but I think I understand now what you mean by closure – DCR Feb 26 '18 at 18:14
  • @DCR That log statement doesn't have access to the closure, but the lambda does. Closures are one of those weird concepts that makes no sense until suddenly it clicks and then it seems blindingly obvious and you wonder why you had such a hard time. FP is chock-full of that sort of thing. – Jared Smith Feb 26 '18 at 18:15
  • I got that but in the first example i is still alive at the return so the functions get evaluated at 5 – DCR Feb 26 '18 at 18:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165852/discussion-between-jared-smith-and-dcr). – Jared Smith Feb 26 '18 at 18:18

0 Answers0