0

function func2() {
  for (let i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 2000);
  }
}

func2();

Due to closure, the console.log statement should remember its outer lexical environment, which is first setTimeout and then the for loop. Since i is not available in the setTimeout context, it looks in the execution context of the for loop, and searches for the value of i there.

Now, that value, after 2 seconds, should have been 3 for all three executions of console.log. But it displays the output as:

0
1
2
Daud
  • 7,429
  • 18
  • 68
  • 115
  • 1
    Does this answer your question? [Functions declared within loops referencing an outer scoped variable may lead to confusing semantics. What is wrong?](https://stackoverflow.com/questions/46027262/functions-declared-within-loops-referencing-an-outer-scoped-variable-may-lead-to) – AndrewL64 Oct 08 '21 at 08:41

1 Answers1

1

You have used let which is block scoped so there will be separate i for each for loop iteration.

1) If you want to output consective 3 so you can declare i outside of for-loop, then there will be only single i with the value 3.

function func2() {
  let i;
  for (i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 2000);
  }
}

func2();

2) If you want same lexical scope then you can also use var here,

var is function scoped, So there will only be one i

function func2() {
  for (var i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 2000);
  }
}

func2();
DecPK
  • 24,537
  • 6
  • 26
  • 42
  • So, each console.log will store a different ancestral lexical environment? I thought that lexical environment were delimited by the ancestor function/s which would be the same for each console.log and in that ancestor function, the value of "i" would be 3. What I now understand is that setTimeout would have a different parent lexical environments stored for each call. Or is it that the lexical environment is the same but the scope of "i" in each call is also stored in the lexical environment – Daud Oct 08 '21 at 09:23
  • Yeah right, You can also use `var` here, `var` is `function-scoped`. Answer udpated – DecPK Oct 08 '21 at 09:45