JS關於for循環中變量作用域的問題

js中作用域只有函數作用域和全局作用域,在函數體內使用var 定義的變量,會被提到函數開始處進行定義,作用域爲整個函數,常見的誤區如下

 1 var a=[];  
 2 for(var i = 0;i<10;i++){  
 3    var q = i;  
 4    a[i]=function(){console.log(q)}  
 5 }  
 6 a[0]()  
 7       
 8 其中,由於for循環並不是一個函數體,所以for循環中定義的變量q和i是作用域for循環所在的函數體,和a同級,  
 9 i++ 和  q=i 並不是重新定義變量,只是重複賦值,最終循環結束,i = 10,q=9;    
10 由於function(){console.log(q)} 並不是立即執行,所以這裏的q一直是存儲的內存引用,最終所有的a[i]()都是輸出 9  
11 不過,在es6中新增了let命令聲明變量,用法和var類似,不過let所聲明的變量,只在let命令所在的代碼塊有效果,for循環的計數器中就很適合let命令  
12 var a=[];  
13 for(let i = 0;i<10;i++){  
14    ley q = i;  
15    a[i]=function(){console.log(q)}  
16 }  
17 a[6]()    //這裏會輸出   6  let聲明的變量僅在塊級作用域有效,所以這裏的i只在本輪循環有效果,每次循環的i其實都是一個新的變量  

 

有兩種方法可以將其變成塊級作用域,一種是使用閉包,第二種就是使用ES6中的let定義變量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章