1

In the following scenario, event setTimeout get queued and only after stack clears out, i = 3 will print 3 times

//ver1
for (var i = 0; i < 3; i ++ ) setTimeout(()=> console.log(i), 3)

The following will print 1 2 3 in order since i is captured in func x ??

//ver2
for (var i = 0; i < 3; i++) {
    (function x(i) {
        setTimeout(() => {console.log(i)}, 30)
    })(i);
}

Why the following only prints 2 one time?

//ver3
for (var i = 0; i < 3; i++) {
    function x(i) {
        setTimeout(() => {console.log(i)}, 30)
    }(i);
}

I'm mostly confused between ver2 and ver3


EDIT: ver2 explanation can be found here. Any insight on why ver3 only prints 2?

jen007
  • 629
  • 2
  • 8
  • 17
  • https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript here you can find answers for your questions – Noob Aug 29 '19 at 02:39
  • https://stackoverflow.com/questions/50615610/why-is-iife-needed-to-create-a-new-scope here is even a better explanation of what is happening in your code – Noob Aug 29 '19 at 02:53
  • but that doesn't explain the behavior of `ver3` – jen007 Aug 29 '19 at 03:56

1 Answers1

1

Your version 3 doesn't do at all what you think it does. Parenthesis are not optional on an IIFE. But because you named the function, it does get parsed as a function declaration:

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

You were never calling x(…) here. The (i) is just an unnecessarily-parenthesised expression evaluating the i variable. Your code executes the same as

for (var i = 0; i < 3; i++) {
    i;
}

So why does this log 2 in the console? Because when you run this on the console, it prints the result value of the statement that was evaluated last: i, which had the value 2 in the last iteration of the loop.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164