分配给新变量时,计数器值在循环内发生变化

时间:2014-12-29 15:45:36

标签: javascript scope

我正在学习JS。为什么记录funcs2[1](); log 4和funcs[1]();会记录5?

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

但那不是我的问题。我想知道为什么funcs2[1](); log 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

3 个答案:

答案 0 :(得分:2)

因为当i增加到5时,它不会进入循环,所以最后x是4。

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

答案 1 :(得分:2)

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

然而,第二种情况中x的值为4,因为这是最后一次迭代索引,i++x = i分配后发生。

答案 2 :(得分:0)

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

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 
相关问题