"Translating" javascript loops and scopes

Source: Internet
Author: User

My translation station: Www.zcfy.cc/article/javascript-loops-and-scope

Translated text link: flaviocopes.com/javascript-loops-and-scope/

JavaScript has a feature that may cause headaches for developers, and is related to loops and scopes.

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 prints out the index value of the loop variable i .

After you run these functions

The expected result should be:

01234

But what actually happens is this:

55555

Why is this happening? Because it's using var .

Because the var variable is promoted, the above code is equivalent to the

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 It is still visible, it is equal to 5, and each time it is involved in the function i , this value will be used.

So what should we do to make it what we think it is?

The simplest scenario is to use a let declaration. Introduced in ES2015, they are a great help to avoid var some strange questions about the use of claims.

Simple in the loop variable will var become let , can run 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:

01234

How does this work? This is because each time the loop repeats, it is recreated i , and each function adds operations an array, which gets its own i .

Remember that you cannot use const in this case, because this will cause for the new value to be tried when the second loop is given an 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 i bind it on top of 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) c2/>}) (i))}for (const operation of Operations) {  operation ()}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

Tags Index: