0
for (var i = 0; i < 3; i++) {
  setTimeout(function log() {
    console.log(i); // What is logged?
  }, 1000);
}

Code ripped from: https://dmitripavlutin.com/javascript-closures-interview-questions/

My output in the console in Firefox 85.0.2 enter image description here

JoePythonKing
  • 1,080
  • 1
  • 9
  • 18
  • 2
    What do you mean with _"twice"_? Why there's `67` and `3`? – Andreas Feb 10 '21 at 09:27
  • 1
    I have no idea what the `67` is; when I try this I get various numbers that keep increasing. The `3` however is the actual output; it is logged three times actually but firefox groups identical outputs. The reason why you're getting 3x3 as opposed to 0,1,2 is that there's only a single var `i` which is `3` when the loop exits. The three timeouts will thus each print `3`. To avoid that, use `let` instead of `var`. –  Feb 10 '21 at 09:29
  • @ChrisG `67` is most likely the `timeoutID` returned by the `setTimeout` – Ivar Feb 10 '21 at 09:30
  • @Ivar But there are three `setTimeout()` calls, hence I would expect three different ids – Andreas Feb 10 '21 at 09:32
  • 1
    @Andreas I don't know the exact details but statements passed to the console generally return a single value. The `for` itself isn't an expression so I _assume_ that it returns the return value of `setTimeout` of the last iteration. That also explains why this value keeps changing. – Ivar Feb 10 '21 at 09:36
  • In Firefox dev tools every log which has _arrow icon_ before it means it is _return_ of what you have just run. FF logs it automatically for each code which is beign run right from the console. Number `67` is probably cumulated from previous logs (I think you tried to run it several times). If you try to log `console.log("x")` you will also get two ouputs - _"x"_ and _"undefined"_ because it returns _undefined_. – Jax-p Feb 10 '21 at 09:38
  • This is a first run in a fresh context (I refreshed the page before running the code in the console). Q. Is the for loop creating 3 settimeout functions? Is the settimeout creating 3 log functions? – JoePythonKing Feb 10 '21 at 09:43
  • Well I've tried it and I get `3` (+3x 3 from your log) from the first run and `6` from the second run etc... In conclusion, I think you can ignore logs which has an arrow icon. – Jax-p Feb 10 '21 at 09:48
  • The loop is creating three timeouts, yes. Each of them will call the function, which in turn will log the current value of `i`, 3. –  Feb 10 '21 at 09:49
  • @JoePythonKing Firefox stacks values if you output the same value multiple times. The "3" I circled [in this image](https://i.stack.imgur.com/mdV92.png) indicates that it logged the value 3, 3 times. – Ivar Feb 10 '21 at 09:50
  • Hmmm, if I do a fast double execution of the console code (cntrl+enter twice in a row) then I get a variable number of repeats indicated by the blue circle next to debugger info. Sometimes it shows 5 repeats or 6 repeats. – JoePythonKing Feb 10 '21 at 10:01
  • There is something I hadn't considered before, that if you declare a function then you create a function, and you can repeatedly create the same named function? I assumed the callback to the settimeout was a single function. In the link, the demonstration uses a webpage app which is not the same as the console. The jsitor seems to create a fresh context every run. – JoePythonKing Feb 10 '21 at 10:03
  • "_Sometimes it shows 5 repeats or 6 repeats._" That's not so odd is it? You have a timeout of 1 second so if you can execute multiple within that second it will stack all outcomes together. – Ivar Feb 10 '21 at 10:10
  • So, settimeout returns a TimeoutID. Simple code to test - setTimeout(()=>{},1000);. And the console prints that value. But, why doesn't it show 3 settimeout return values (if I loop the settimeout in a for loop 3 times)? – JoePythonKing Feb 10 '21 at 10:14
  • @JoePythonKing See [this](https://stackoverflow.com/questions/66134124/why-does-i-get-output-twice-in-the-firefox-console#comment116923286_66134124) previous comment. Firefox seems to return the return value of the last executed statement. – Ivar Feb 10 '21 at 10:19

0 Answers0