We often use JavaScript in our work, and he has a close relationship with our work. But JavaScript has a feature that may cause headaches for developers, which are related to their loops and scopes, and then talk about their relationship.
As an example:
Const OPERATIONS = []for (var i = 0; i < 5; i++) { Operations.push (() = { Console.log (i) })}for (const Operation of Operations) { operation ()}
It basically loops 5 times and adds a function to the operations array. This function can print out the index value of the cyclic variable i.
The expected result after running these functions should be:
0 1 2) 3 4
But what actually happens is this:
5 5 5) 5 5
Why is this happening? Because Var is used. Because the Var variable is promoted, the above code is equivalent to
var i;const operations = []for (i = 0; i < 5; i++) { Operations.push (() = { Console.log (i) })}for (cons T operation of Operations) { operation ()}
Therefore, in the for-of loop, I is still visible, it is equal to 5, and each time I is involved in the function, this value will be used.
So what should we do to make it what we think it is?
The simplest scenario is to declare with let. As described in ES2015, they are a great help to avoid some strange questions about using Var declarations.
It is simple to turn Var into a let in the loop variable, which works well:
Const OPERATIONS = []for (Let i = 0; i < 5; i++) { Operations.push (() = { Console.log (i) })}for (const Operation of Operations) { operation ()}
Here is the output:
0 1 2) 3 4
How does this work? This is because each time the loop repeats, I is recreated, and when each function adds a operations array, it can get the I of itself.
Remember that you cannot use const in this case, because this causes the for in the second loop to attempt to assign a new value to the error.
Another very common solution to this problem is to use the PRE-ES6 code, which is called an instant call function expression (iife).
In this case, you can wrap the entire function and bind I to it. From this way, you are creating a function that can execute immediately, and you return from it with a new function. So we can execute it later.
Const OPERATIONS = []for (var i = 0; i < 5; i++) { Operations.push ((j) = { return () = Console.log (j) c6/>}) (i))}for (const operation of Operations) { operation ()}