2011-04-02 61 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