在Javascript中关闭混乱

时间:2011-04-02 03:35:28

标签: javascript closures

示例1:http://jsfiddle.net/ufCr8/

function createFunctions() {
    var result = new Array();

    for (var i = 0; i < 10; i++) {
        result[i] = function() {
            return i;
        }();
    }

    return result;
}

var funcs = createFunctions();       
for (var i = 0; i < funcs.length; i++) {
    document.write(funcs[i] + "<br />");
}

示例2:http://jsfiddle.net/T5shB/

function createFunctions() {
    var result = new Array();

    for (var i = 0; i < 10; i++) {
        result[i] = function(num) {
            return function() {
                return num;
            };
        }(i);
    }

    return result;
}

var funcs = createFunctions();
for (var i = 0; i < funcs.length; i++) {
    document.write(funcs[i]() + "<br />");
}

为什么这两个会得到不同的结果?

1 个答案:

答案 0 :(得分:3)

这两个都正常工作。 (并得到相同的结果)。

示例#1:

for (var i = 0; i < 10; i++) {
    result[i] = function() {
        return i;
    }(); // note function application!
}

匿名函数执行然后,结果是循环中每次迭代的{{1>}值{{1>}。这实际上与i相同。不是很令人兴奋。 (在打印出值的循环中,没有函数应用程序,如果不是函数,则会出现错误,因为它与下面的示例不同。)

示例#2:

result[i] = i

应用的外部匿名函数返回一个闭包,该闭包正确地“双重绑定”到for (var i = 0; i < 10; i++) { result[i] = function(num) { return function() { return num; }; }(i); } 当前值,该值以i传递({{ 1}}实际上是绑定的自由变量)。请记住,函数引入了一个新的范围 - num(或num)没有。

我怀疑“失败案例”将是:

var

这将产生“奇怪的结果”,因为它是相同的for,它绑定在每个闭包中(即for (var i = 0; i < 10; i++) { result[i] = function() { return i; }; // note function NOT invoked here! } ... for (var i = 0; i < funcs.length; i++) { document.write(funcs[i]() + "<br />"); } 是自由变量而那里只有一个i )。因此,当执行该函数时,它将在执行时返回当前值i

快乐编码


我建议阅读Jibbering JavaScript Closure Notes - 它不是最初学者资源,但我发现它可以访问,并且它足够详细地解释了一些内容。 (并且远比ECMAScript规范,IMOHO更具可读性。)