function y() {
for (var i = 1; i <= 5; i++) {//‘for loop’ will go and register 5 setTimeouts(). when it comes last time, it will do i++, then check i <= 5? will return false and loop will be finished, BUT i has been already incremented and it has value of 6. Because i is a ‘var’’, and not ‘let’ when it’s come to execute setTimeout() the ‘var’ will be always the value last initialized to i, so 6. In other words ‘i’, in the end, will be reinitialized with its last value ===6.
setTimeout(function () {
console.log(i);
}, i * 1000);
}
}
y();
Ill start with the second function (y). In the first iteration of the loop, you say, log the value of i after one second. Before that time runs out, the entire loop has processed, all its iterations ran, so i is already of value 6. At the one second mark, i will be 6 and thats what you see in the console.
In the first loop(x), you pass the value of i to a function, as an argument. The function wont log the current value of i, it will log the value it received as an argument. It doesnt practically log i, but the value it recieved on its call. In the first iteration of the loop, the repeat function was called with an argument of 1 and that is what it logs.
This is why you should drop var out your dictionary and stick to let and const. They are much more explicit on what they are doing and how they are supposed to work(well one can argue on const), while var can produce those confusing and often unpredictable behaviors(they are predictable but you need to dive in specifics that is hard to keep track of and b entirely aware, which also renders it unfit to work with in many cases).