6个6

let i for(i=0; i<6; i++){ setTimeout(()=>console.log(i),1000) }Copy the code

This code will eventually print out six sixes.

I =0: setTimeout(console.log(I),1000), after 1s, print I. Some people say, now I equals 0, why not print 0? Because the console.log function hasn’t been executed yet, it’s just been defined. When not implemented, js does not care about the contents.

I =1: setTimeout(console.log(I),1000), after 1s, print I again, not 1.

All the way to I is equal to 5. And then I equals 6, you break out of the loop. So the for loop is over, and let’s see if it’s 1s, and if it’s not, then it’s not going to print. It’s 1s, and it’s not busy yet, so let’s go and execute the function.

If the following function takes a long time, then the setTimeout(fn(),1000) will be executed after the following function is finished. SetTimeout (fn(),1000) means to execute as soon as possible after 1000ms, which means that it can only be executed within 1000ms.

The function is console.log(I), and the value of “I” is displayed. Now I is equal to 6, so print 6. I have five more functions, console.log(I), I is still 6, so I just print 6 all the time.

So what you end up with is you print six sixes.

Bottom line: Functions are executed when they are called, and variable values are looked at when they are executed.

How do I print 0,1,2,3,4,5?

The reason it prints out six sixes is because when the function doesn’t execute, it doesn’t look at what’s inside. When I goes from 0 to 1, the 0 is gone, and so on, everything in between is gone.

So let’s save the middle value and print the saved value.

let i for(i=0; i<6; i++){ let j=i setTimeout(console.log(j),1000) }Copy the code

I =0: let j=0, setTimeout(console.log(j),1000) after 1s, print j

I =1: let j=1, setTimeout(console.log(j),1000

Some people say, when I equals 1, doesn’t j become 1, so the first j that’s printed out is going to be the new value?

Note that a let is scoped, starting with {and ending with}. In other words, each time I loop, it’s a new scope, and in each new scope, j is actually different, not interfering with each other.

When I equals 0, in the first scope, j equals 0, it’s always 0.

At I =1, it’s a new scope, and in this new scope, j=1, it’s always 1.

The essence is that j1, J2, and J3 are different.

So it’s going to print 0,1,2,3,4,5

Syntactic sugar

Instead of writing let j= I, add a “let” before the “I” of the “for” loop to have the same effect.

for(let i=0; i<6; i++){ setTimeout(console.log(i),1000) }Copy the code

Result: print 0,1,2,3,4,5

Adding a let will automatically create an invisible I ‘for us every time we enter the loop, just like a j, and it will actually print the I’, and it will hold the middle value

Immediate execution function

In addition to holding intermediate values in lets, there is a second way to execute the function immediately.

Var has no scope.

Every time we loop, we immediately execute an anonymous function, passing the I as an argument to its parameter. Because the anonymous function is executed, the j inside (j can be called I, the first bracket is the parameter, the last is the argument) determines the value, which is 0,1,2,3,4,5 every time. So at the end of the for loop, it will print the 0,1,2,3,4,5 that has been set