Home > Article > Web Front-end > Analyze the relationship between JavaScript loops and scope (with code)
We often use JavaScript in our work, and it is closely related to our work. But JavaScript has a feature that may cause headaches for developers, and it is related to loops and scopes. Let’s talk about the relationship between them next.
For 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 loop variable index value 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. Since 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 (const operation of operations) { operation() }
Therefore, in for-of During the loop, i is still visible, it is equal to 5, and this value will be used every time i is referenced in the function.
So what should we do to make it what we want?
The simplest solution is to use let declarations. Introduced in ES2015, they are of great help and can avoid the confusion about using var declarations. Some strange questions.
Simply change var into let when looping variables, it can run well:
const operations = [] for (let i = 0; i < 5; i++) { operations.push(() => { console.log(i) }) } for (const operation of operations) { operation() }
This is the output result:
0 1 2 3 4
How is this achieved? This is because every time the loop is repeated, i will be recreated, and each function can obtain its own i when it adds to the operations array.
Remember that you cannot use const in this case, because this will cause for to report an error when trying to assign a new value during the second loop.
Another very common solution to this problem is to use pre-ES6 code, and it is called an immediately invoked function expression (IIFE).
In this case, you can wrap the entire function and pass i Bind to it. This way, you are creating a function that can be executed immediately, and you return a new function from it. So we can execute it later.
const operations = [] for (var i = 0; i < 5; i++) { operations.push(((j) => { return () => console.log(j) })(i)) } for (const operation of operations) { operation() }
The above is the detailed content of Analyze the relationship between JavaScript loops and scope (with code). For more information, please follow other related articles on the PHP Chinese website!