2012-06-19 48 views
1

我在閱讀「Javascript:The Good Parts」一書中有關關閉的內容。「Javascript:The good parts」中關閉的示例

還有就是下面的示例中使用閉包的:

var add_the_handlers = function (nodes) { 
var i; 
    for (i = 0; i < nodes.length; i += 1) { 
     nodes[i].onclick = function (i) { 
     return function (e) { 
      alert(i + ":" + e); 
     }; 
     }(i); 
    } 
}; 

它是正確的例子嗎?或者更正確的例子將是?

var add_the_handlers = function (nodes) { 
var i; 
    for (i = 0; i < nodes.length; i += 1) { 
     nodes[i].onclick = function (idx) { 
     return function (e) { 
      alert(idx + ":" + e); 
     }; 
     }(i); 
    } 
}; 

變量i在內部函數 「節點[I] .onclick =函數(I)」 外部函數和變量i - 這是兩個不同的變量。 第三個函數從第二個函數訪問變量,而不是從最外層訪問變量。
我正確嗎?

+1

兩個版本都做同樣的事情。在我看來,你的版本更易於閱讀,因爲變量名稱不同。一般來說,當您在不同範圍內具有相同名稱的變量時,將使用的變量是最接近(或在)當前範圍內定義的變量。 – nnnnnn

回答

2

這兩個例子是相同的。閉包的全部要點是將一個外部變量(i)變爲一個內部變量(i/idx/foo,隨你選)。閉包創建變量的「副本」,以便在回調進行時,它具有正確的值。

// outer-scoped i changes on each iteration 
var i; 

for (i = 0; i < nodes.length; i += 1) { 
    nodes[i].onclick = function (i) { 

     // here i now refers to a different variable; while the outer i keeps iterating, 
     //this i is preserved at its current value. 
     return function (e) { 
     alert(i + ":" + e); 
     }; 
    }(i); 
} 
+0

你確定閉包是否創建了變量的「副本」?從書中 - 「重要的是要明白,內部函數可以訪問外部函數的實際變量 而不是副本,以避免以下問題」。 –

2

是的,例子正確。您看到的作爲函數參數的i變量優先於外部變量i,因爲它在本地作用域中聲明。

0

從javascript的角度來看 - 這兩個是相同的。所以這是品味的問題。如果你在裏面會有更多的關閉,那麼使用不同的名字是個好主意。但是這裏的例子非常簡單 - 沒有必要這樣做。

+0

從javascript的角度來看 - 這兩個例子是相同的。但是很難理解,在下面的函數調用中有兩個不同的變量 - 「function(i){}(i)」。 –

0

不,您發佈的兩個示例完全相同。唯一的區別就是函數的參數名稱,但這並不重要,你可以使用任何參數。

相關問題