2012-08-22 57 views
0

以下方法的使用有什麼不同?在js節點中使用閉包

第一種方法:

for(var i = 0; i < 10; i++) { 
    (function(e){ 
     setTimeout(function() { 
      console.log(e); 
     }, 1000); 
    })(i); 
} 

for(var i = 0; i < 10; i++) { 
    createTimeoutFunction(i); 
} 

第二種方法:

function createTimeoutFunction(e){ 
    setTimeout(function() { 
     console.log(e); 
    }, 1000); 
} 

for(var i = 0; i < 10; i++) { 
    createTimeoutFunction(i); 
} 

我新的節點JS和使用閉。儘管這兩種方法都返回相同的輸出,但第二種方法運行時出錯。我不明白爲什麼我們需要像第一種方法那樣使用兩個循環。我們不能像第二種方法那樣執行嗎?

+6

第一種方法是有點馬車,因爲'createTimeoutFunction'不存在 – EaterOfCode

+0

沒有第二種方法給予什麼樣的錯誤呢? – raina77ow

+0

@ raina77ow如果我嘗試在終端用於將打印第二方法上面的代碼'陣列 布爾 日期 錯誤 的EvalError 功能 無窮 JSON 數學 的NaN 編號 對象 的RangeError 的ReferenceError 正則表達式 字符串 語法錯誤 類型錯誤 URIError decodeURI decodeURIComponent encodeURI encodeURIComponent方法 EVAL isFinite的 isNaN parseFloat parseInt函數 未定義 '10次爲'函數createTimeoutFunction(E){'。這是爲什麼? – user850234

回答

0

閉包在JavaScript的工作,無論環境或解釋您使用的是相同的。

的封閉提供了一個特定的變量範圍,其中該組的代碼執行。你的閉包可以訪問(明顯)自己定義的任何東西,以及任何封閉閉包中定義的任何對象。

與您編寫了該問題存在,在第一個例子createTimeoutFunction不被任何定義 - 當你調用它,它就會失敗。在這個例子中:

(function(e){ 
    setTimeout(function() { 
     console.log(e); 
    }, 1000); 
})(i); 

在這個閉包中定義的函數是一個匿名函數。它沒有name屬性,不能被引用。

第二個版本定義了一個全局變量createTimeoutFunction這是再因爲它是全局對象的部分頁面上的任何封閉訪問。 (嗯,我假設,因爲你沒有顯示這個代碼被其他東西包含)。

1

在你的第一個方法取出第二for,因爲除非你想在循環運行兩次,它是多餘的,因爲一切都已經在第一發生。第二個循環失敗,因爲createTimeoutFunction永遠不會被定義在第一個循環範圍之外,與第二個方法相反。

除此之外,它們都將產生相同的結果,在第二方法中createTimeoutFunction是唯一的差別是可重複使用的。

參見:How do JavaScript closures work?