for var let閉包理解

let、 var、 setTimeout,一點思考。javascript

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

 

結果是很顯而易見的,10次都是10,在面試前端的閉包知識時候很常見。 
用上let以後,前端

for(let i = 0; i < 10; i++){ setTimeout(function(){ console.log(i); },100); }

 

結果是: 
0、一、二、三、四、五、六、七、八、9java

爲何var和let聲明的i,獲得不一樣的結果?面試

var聲明的i,做用域不單單在for循環內,還在for循環的外部。閉包

當setTimeout執行的時候,for循環已經完成,i此時的值是10,咱們稍微調整一下代碼:函數

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

結果是10次10。ui

for(var i = 0; i < 10; i++)

 

spa

var i; for(i = 0; i < 10; i++)

 

等價。code

可是在let聲明的時候則不同,ip

for(let i = 0; i < 10; i++)

 

let i; for(i = 0; i < 10; i++)

是不等價的,由於let聲明只在代碼塊中有效。 
可是,若是僅僅這樣,咱們或許很容易理解

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

 

獲得10次10,然而爲何

for(let i = 0; i < 10; i++){ setTimeout(function(){ console.log(i); },100); }

 

獲得0-9?

在setTimeout的時候,匿名函數function(){console.log(i);}會被聲明建立,當匿名函數執行的時候,會查找當前運行環境的 i 的值。 
var聲明的 i ,運行環境的 i 的值爲10,可是let聲明的 i,運行環境中 i 的值是每個循環建立匿名函數時候的 i。 
因此獲得了0-9的值。

let替換var,能夠很好的解決閉包的問題。

相關文章
相關標籤/搜索