The questions to be discussed in this article are:
- Why does the following code print six 6’s instead of 0, 1, 2, 3, 4, 5
- How to rewrite the following code so that it prints 0, 1, 2, 3, 4, 5
The code is as follows:
let i = 0 for(i = 0; i < 6; i ++){ setTimeout(() = >{ console.log(i) }, 0)}Copy the code
Let’s look at the case where there is no setTimeout
let i = 0
for(i = 0; i < 6; i ++){
console.log(i)
}
// Output 0, 1, 2, 3, 4, 5
Copy the code
The for loop loops the variable I from 0 to 6 times, each time printing out the current value of I: 0, 1, 2, 3, 4, 5. When I is 6, the condition is not satisfied and the loop ends.
If we add setTimeout to the body of the loop, the situation is different:
let i = 0
for(i = 0; i < 6; i ++){
setTimeout(() = >{
console.log(i)
}, 0)}// Output 6 6 6 6 6 6 6
Copy the code
In the above code, I is still iterated from 0 to 6, but because setTimeout is used, console.log is not executed immediately, but “executed as soon as possible”. The console. Log function is executed as soon as possible after the for loop is complete. Since the value of I has changed to 6 by the end of the for loop and six console. logs have not been executed, the console.log is executed six times, printing six 6’s.
How to print 0, 1, 2, 3, 4, 5 while using setTimeout?
for (let i = 0; i < 6; i ++) {
setTimeout(() = > {
console.log(i)
}, 0)}// Output 0, 1, 2, 3, 4, 5
Copy the code
In this code, we put the let declaration variable inside the for loop. In other words, if we use let and for together, JS creates one more I for each pass. Each pass I is different, so we end up with a different output instead of six sixes.
If you use VAR instead of let, you can solve this problem with immediate execution functions and closures
for (var i = 0; i < 6; i ++) {
!function (i) {
setTimeout(() = > {
console.log(i)
}, 0)
}(i)
}
// Output 0, 1, 2, 3, 4, 5
Copy the code
This code calls an anonymous function for each iteration, passing the current I to the anonymous function, and printing out I “as soon as possible.” Because each iteration calls an anonymous function, by the time the for loop is finished, six anonymous functions are called. Each of these anonymous functions has its own scope, and each of these anonymous functions is passed a different parameter, so it ends up printing six different values.