分配给新变量时,计数器值在循环中更改

Counter value changes within loop when assigned to a new variable

本文关键字:计数器 循环 新变量 变量 分配      更新时间:2023-09-26

我正在学习JS。为什么日志记录funcs2[1]();日志 4,funcs[1]();日志 5?

请注意,这不是这个问题的重复。我知道funcs[1]();记录5(而不是 1),因为调用的函数绑定到 i 的当前值,当循环终止时为 5。

但这不是我的问题。我想知道为什么funcs2[1]();日志 4 而不是 5。

var funcs = [];
for (var i = 0; i < 5; i++) {
    funcs.push(function () {
        return i;
    });
}
console.log(funcs[1]());
5
var funcs2 = [];
for (var i = 0; i < 5; i++) {
    var x = i;
    funcs2.push(function () {
        return x;
    });
}
console.log(funcs2[1]());
4

由于 javascript 中没有块作用域,因此在两个循环都完成执行后,变量 i 的值在这两种情况下都是5的。

但是,在第二种情况下,x的值是4的,因为这是最后一次迭代索引,i++ x = i赋值后发生。

因为当 i 增加到 5 时,它不会进入循环,因此最终 x 为 4。

这是一个著名的 JS 闭包问题,内部函数仅将父上下文的变量对象保留在其内部 [[scope]] 属性中,而不是变量中。 因此,当循环完成时,父对象的 Vairable 对象中的i等于 5,而 X 等于 4。

抱歉,我对原始帖子的编辑被拒绝了。 为了进一步讨论这个问题,我用另一个案例来回答:

var funcs3 = [];
function foo() {
    for (var k = 0; k < 5; k++) { // k is in foo's scope
        funcs3.push(function () {
            return k;
        });
    }
}
foo(); // k can't be accessed after from here
console.log(funcs3[1]()); // 5, k is still in closure