2011-04-02 62 views
1

示例1:http://jsfiddle.net/ufCr8/封闭混乱的Javascript

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 />"); 
} 

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

+2

他们对我来说有相同的结果。 – icktoofay 2011-04-02 03:37:02

+0

是的,对我来说也是一样的结果。你在使用一个奇怪的浏览器吗? – 2011-04-02 03:42:57

+0

我也得到了同样的结果。请注意,这些函数全部在for循环中执行,因此分配给'result [i]'的值被“冻结”。如果你想在for循环外部移除'()'并运行'result [i]()',你会看到一个'9'列表被打印出来。 – monsur 2011-04-02 03:43:42

回答

3

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

样品#1:

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

匿名功能被执行右然后,其结果是许多i每次迭代通过循环(当前)值。这实际上与result[i] = i相同。不是很令人兴奋。 (在打印出数值的循环中,没有函数应用程序,如果不是函数,它将作为数字出现错误 - 在这种情况下,它与以下示例不同)。

样本#2:

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

施加外匿名函数返回一个封闭其正确“双结合”被传递作为numi电流值(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自由变量和只有一个i)。因此,当执行该功能时,它将在执行点处返回i的当前值

快乐编码


我会推荐阅读Jibbering JavaScript Closure Notes - 这不是最初级的资源,但我觉得它可以访问它足够详细解释的事情。 (而且远远超过ECMAScript规范(IMOHO)的可读性。

+1

这是一个很好的例子,为什么在函数周围使用明确的括号可以立即调用,即使他们没有必要,就像在这种情况下一样。 – Reid 2011-04-02 03:51:11

+0

谢谢你。你的回答非常有帮助。祝你今天愉快。 – jsnewman 2011-04-02 04:14:46