問題:
A friend of mine and I are currently discussing what is a closure in JS and what isn't. 個人一個朋友和我正在討論什麼是JS的封閉,什麼不是。 We just want to make sure we really understand it correctly. 咱們只是想確保咱們真正理解它。 閉包
Let's take this example. 咱們來看看這個例子吧。 We have a counting loop and want to print the counter variable on the console delayed. 咱們有一個計數循環,並但願在控制檯上打印計數器變量延遲。 Therefore we use setTimeout
and closures to capture the value of the counter variable to make sure that it will not print N times the value N. 所以,咱們使用setTimeout
和閉包來捕獲計數器變量的值,以確保它不會打印N倍N值。 app
The wrong solution without closures or anything near to closures would be: 錯誤的解決方案,而閉合或接近閉合 ,以將任何東西: 函數
for(var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); }, 1000); }
which will of course print 10 times the value of i
after the loop, namely 10. 這將固然打印的10倍的值i
在循環後,也就是10。 oop
So his attempt was: 因此他的嘗試是: this
for(var i = 0; i < 10; i++) { (function(){ var i2 = i; setTimeout(function(){ console.log(i2); }, 1000) })(); }
printing 0 to 9 as expected. 按預期打印0到9。 spa
I told him that he isn't using a closure to capture i
, but he insists that he is. 我告訴他,他並無使用封閉來捕獲i
,但他堅持認爲他是。 I proved that he doesn't use closures by putting the for loop body within another setTimeout
(passing his anonymous function to setTimeout
), printing 10 times 10 again. 我經過將for循環體放在另外一個setTimeout
(將他的匿名函數傳遞給setTimeout
),再次打印10次10來證實他沒有使用閉包 。 The same applies if I store his function in a var
and execute it after the loop, also printing 10 times 10. So my argument is that he doesn't really capture the value of i
, making his version not a closure. 若是我將他的函數存儲在var
並在循環以後執行它一樣適用,也打印10次10.因此個人論點是他並無真正捕獲 i
的值 ,使他的版本不是一個閉包。 .net
My attempt was: 個人嘗試是: code
for(var i = 0; i < 10; i++) { setTimeout((function(i2){ return function() { console.log(i2); } })(i), 1000); }
So I capture i
(named i2
within the closure), but now I return another function and pass this around. 因此我捕獲了i
(在閉包中命名爲i2
),但如今我返回另外一個函數並傳遞它。 In my case, the function passed to setTimeout really captures i
. 在個人例子中,傳遞給setTimeout的函數實際上捕獲了i
。 ip
Now who is using closures and who isn't? 如今誰在使用閉包,誰不是? get
Note that both solutions print 0 to 9 on the console delayed, so they solve the original problem, but we want to understand which of those two solutions uses closures to accomplish this. 請注意,兩個解決方案在控制檯上打印0到9都會延遲,所以它們解決了原始問題,但咱們想要了解這兩個解決方案中的哪個使用閉包來實現此目的。
解決方案:
參考一: https://stackoom.com/question/sFkm/JavaScript閉包與匿名函數參考二: https://oldbug.net/q/sFkm/JavaScript-closures-vs-anonymous-functions