Function cannot use variable value of external loop normally

Function cannot use variable value of external loop normally

When we use a setTimeout function in the for loop, we will find that there is a problem with the variables of the external loop in each function. js code is as follows:

Initial code:

<script>
    var arr=[1,2,3]
    for (var i = 0; i <arr.length; i++) {
        setTimeout(function(){
           console.log(arr[i])
        })
    }
</script>

Initial code output:

Our output results on the console are:

Initial code collation:

This problem occurs because the for loop is a synchronous task, while setTimeout is an asynchronous function. When the code is executed, the for loop will execute until the conditions are not met, and then execute the asynchronous tasks in setTimeout. Let's sort out the code. In fact, it's like this:

<script>
var arr=[1,2,3];
var i;
i=0;
i=1;
i=2;
i=3;
setTimeout(function () {
            console.log(arr[i])
        })
setTimeout(function () {
            console.log(arr[i])
        })     
setTimeout(function () {
            console.log(arr[i])
        })
</script>

When the for loop ends, the value of variable i is 3, and the console outputs three times of arr[3], that is, three times of undefind. The solution is:

Method 1: use self calling function

Method 1 Code:

<script>
    var arr = [1, 2, 3]
    for (var i = 0; i < arr.length; i++) {
        (function(i){
            setTimeout(function () {
            console.log(arr[i])
        }) 
        }(i))
    }
</script>

Method 1 code output:

Method 1 code sorting:

The problem is solved because when we use a function to package the asynchronous function and pass in parameters, it is equivalent to redefining a variable and assigning a value in the function every time. The sorting code is as follows:

<script>
var arr=[1,2,3];
var i;
i=0;
i=1;
i=2;
i=3;
(function(i){
    vari;
    i=0;
    setTimeout(function () {
    console.log(arr[i])
        }) 
        }(i))
(function(i){
    vari;
    i=1;
     setTimeout(function () {
    console.log(arr[i])
        }) 
        }(i))
(function(i){
    vari;
    i=2;
    setTimeout(function () {
    console.log(arr[i])
        }) 
        }(i))
</script>

Method 2: use let to define loop variables

Method 2 Code:

<script>
    var arr = [1, 2, 3];
    for (let i = 0; i < arr.length; i++) {
        setTimeout(function () {
                console.log(arr[i])
        })
    }
</script>

The output result is the same as the self calling function; because we define variables by replacing var with let, which limits the scope of variables, the code execution process is similar to the self calling function, and it is also the easiest method.

Method 3: use index to record Subscripts

Method 3 code:

<script>
    var arr = [1, 2, 3];
    for (let i = 0; i < arr.length; i++) {
        arr[i].index=i;
        setTimeout(function () {
                console.log(arr[i])
        })
    }
</script>

At this time, the console output is also 1,2,3

Conclusion:

In fact, the key to this problem is that using var to define variables will have a process of variable promotion, making it a global variable. We will try to limit the scope of variables and turn it into a local variable to use.

Added by cjl on Sat, 26 Oct 2019 23:03:39 +0300