ES6: Compare Scopes of the var and let Keywords. Help with understanding required

Hello, fellow campers, could you, please, help me understand, why console.log(i) returns 3 in this example?
I dont want to move further without thorough understanding of the issue.
Many thanks in advance!

The code in question

var numArray = [];
for (var i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
console.log(i);
// returns 3

browser information:

User Agent is: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 OPR/55.0.2994.61.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/es6/compare-scopes-of-the-var-and-let-keywords

With the var keyword, i is declared globally. So when i++ is executed, it updates the global variable.

This function was created to fill an empty array with numbers from 0 to 2, so how come the i variable means 3?

The i++ executes at the end of each loop, so i ends at 3.

1 Like

This gets asked a lot, because I suspect we don’t necessarily explain very well what actually happens around a for loop

This is going to possibly be a confusing explanation to read but it might help in future for other loop related questions you may have

When we have for(a; b; c){d; } where a, b, c, d are parts of the for loop, the following happens:

  1. The expression a is executed once
  2. The body of the loop, d, is executed once
  3. c is executed once
  4. b is executed, and if truthy (or true) go back to 2.
  5. otherwise, continue with the line after the loop body

Note that c is executed before b's test

The different keywords var and let control which scopes a variable is still defined in, and behave differently for variables defined in the a part of the loop, but that’s what this question will end up showing so I’ll leave it here

3 Likes

RIGHT! i++ executes at the end of the loop! So when the counter has reached 2 and pushed this number into the array, the counter still increments it one mor time. After that the loop is ready to run one more time, but the expression “b” fails the test, so we end up with the array that goes [0, 1, 2], but the counter variable went one step further.

Thank you very much, I think I’ve got it!

1 Like

Hi, I’m having the same problem. I’ve read @gebulmer explanation but if what he is saying is true then
this function should return 2 not 3:

var printNumTwo;
for (var i = 0; i < 3; i++) {
if(i === 1){
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
// returns 3

There is some reason for which you are creating the function inside the loop? And then calling it outside the loop?

Anyway, as you are calling the function as last line of your code, it uses the values that the variables have at the point in which the function is called, and at that point i is 3

If you instead wanted to call the function inside the loop, see that the if statement works only if i === 1 so in that case it would print 1

What was that you wanted to do with this?

Heya, sorry for slow reply

I realise in hindsight my explanation is slightly wrong actually, but the important point is:

i gets incremented and then tested against the condition

So i first becomes 3, and then the condition becomes false, exiting the loop. That change isn’t undone