JS Scope&关闭头痛

时间:2013-12-02 23:51:44

标签: javascript

请参阅代码,该代码解释了超过1000个单词。我不明白,为什么所有5个创建的函数总是返回5(最后一次迭代值)。我真的很感兴趣,有什么不对或我错过了什么。我记得敢说,道格拉斯·克罗克福德谈过这件事,但我也没有找到那个资源。

function createFunctions(n) {
    var arrayFunctions = [];

    for (var i=0; i<n; i++) {
        arrayFunctions.push(function() {
            console.log(i);
        });
    }

    return arrayFunctions;
}

var arrayFunctions = createFunctions(5);

arrayFunctions[2]();  // returns 5 instead of 2
arrayFunctions[3]();  // returns 5 instead of 3
arrayFunctions[4]();  // returns 5 instead of 4

3 个答案:

答案 0 :(得分:3)

函数正在关闭变量,而不是变量的值。这意味着它们都引用循环中定义的i并在每次迭代时更新。到createFunctions返回时,循环已完成,i处于其最终值(5)。

function createFunctions(n) {
    var arrayFunctions = [];

    for (var i=0; i<n; i++) { 
        (function(j) {
            arrayFunctions.push(function() {
                console.log(j);
            });
        }(i));
    }

    return arrayFunctions;
}

答案 1 :(得分:1)

这是因为函数保留在i的引用上,而不是i的值。

答案 2 :(得分:0)

不确定它是否是最佳方式,但您可以创建一个函数来返回存储正确范围变量的函数:

function createFunctions(n) {
    var arrayFunctions = [];
    for (var i=0; i<n; i++) {
        var scopedFunction = function(scopedI) {
            return function() {
                 console.log(scopedI);
            }
        }
        arrayFunctions.push(scopedFunction(i));
    }

    return arrayFunctions;
}

我在jsfiddle中测试了它,它似乎给出了预期的结果。