0

Why do I get a different output when using a do/while loop in the code below?

function logNum() {
  let counter = 0;

  do {
    counter += 1;
    setTimeout(() => console.log(counter), counter * 1000);
  } while(counter <= 10);
}

logNum();

The above code outputs number 11 ten times. Expected output was numbers 1 to 10. But when I use a for loop, it works as expected as shown below. Why?

function logNum() {
  for (let counter = 1; counter <= 10; counter += 1) {
    setTimeout(() => console.log(counter), counter * 1000);
  }
}

logNum();

Updated working code from example 1:

function logNum() {
  let counter = 0;

  do {
    let num;
    counter += 1;

    num = counter;
    setTimeout(() => console.log(num), num * 1000);
  } while(counter < 10);
}

logNum();
noSelf_
  • 29
  • 5
  • 4
    because in the second example (due to the use of `let`) `counter` is scoped to the loop, whereas in the first one it's scoped to the whole function, so is 11 by the time the timeout functions actually runs – Robin Zigmond Dec 04 '22 at 14:23
  • @RobinZigmond Thank you for the explanation. Your explanation along with the code example by dangarfield below explains it successfully. I've updated the first code snippet as per the new understanding. – noSelf_ Dec 04 '22 at 15:19

1 Answers1

1

The first increments the counter very quickly and then when the setTimeout function triggers, the counter has already been incremented.

Run this below and you will see.

function logNum() {
  let counter = 0;

  do {
    counter += 1;
    console.log('A in loop',counter),
    setTimeout(() => console.log('A in timeout',counter), counter * 1000);
  } while (counter <= 10);
}

function logNum2() {
  for (let counter = 1; counter <= 10; counter += 1) {
    setTimeout(() => console.log('B',counter), counter * 1000);
  }
}

logNum()
logNum2()

Update. I've just re-read the question - This answer is here: What is the scope of a 'while' and 'for' loop?

dangarfield
  • 2,210
  • 1
  • 13
  • 18
  • 2
    "*increments the counter very quickly and then when the setTimeout function triggers, the counter has already been incremented*" - that's also what happens in the second loop – Bergi Dec 04 '22 at 14:27
  • @dangarfield Thank you for the explanation. Your code example and the explanation by Robin above explains it successfully. – noSelf_ Dec 04 '22 at 15:22