The problem of cyclic variables in the return function of js closure

function count() {
    var arr = [];
    for (var i=1; i<=3; iPP) {
        arr.push(function () {
            console.log(i)
            return i * i;
        });
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
console.log(f1(),f2(),f3()) //4 4 4 16

recently, I was watching Liao Xuefeng"s js tutorial. I was a little confused here. Why did I go to the last iTunes 4 ? The condition in the loop statement writes I < = 3 . I hope a great god will give me some advice.

Apr.02,2021
The

decision is made in for. When the cycle of iComple3 is over, iPP, will be given a condition decision again, so I ends up with 4


.

I < = 3 is to stop the for loop, but at this point the value of I is 4 .

what's left is the scope of the closure.


I < = 3, that is, iTunes 3 will enter the following cycle, and the current loop will be iTuned 1


after the execution of iPP. The

for loop is judged to be postset. You can simply understand it as:
the first time: the condition holds, the cycle continues;
the second time: the condition holds, the cycle continues;
the third time: the condition holds, the cycle continues;
the third time: the condition holds, the cycle continues;
the fourth time: the condition is established, the cycle ends. The variable item4 is saved, the value of I is no longer changed, and the contents of the loop body are no longer executed.

Why does the function always get I 4 in the body of the for loop? that's because this function is not executed at all, but only declares an anonymous function, so it won't save the value of I at that time, but just keep a reference to the memory location of I . To save the value of the I loop s, you can use closures.


function count() {
    var arr = [];
    for (let i=1; i<=3; iPP) {
        arr.push(function () {
            console.log(i)
            return i * i;
        });
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
console.log(f1(),f2(),f3()) //1 2 3 1 4 9
Menu