注:文章均來源于網(wǎng)絡
js中作用域只有函數(shù)作用域和全局作用域,在函數(shù)體內(nèi)使用var 定義的變量拼坎,會被提到函數(shù)開始處進行定義,作用域為整個函數(shù),常見的誤區(qū)如下
var a=[];?
for(var i = 0;i<10;i++){?
? var q = i;?
? a[i]=function(){console.log(q)}?
}?
a[0]()?
其中荣刑,由于for循環(huán)并不是一個函數(shù)體措嵌,所以for循環(huán)中定義的變量q和i是作用域for循環(huán)所在的函數(shù)體,和a同級谤辜,?
i++ 和? q=i 并不是重新定義變量蓄坏,只是重復賦值,最終循環(huán)結束丑念,i = 10,q=9;? ?
由于function(){console.log(q)} 并不是立即執(zhí)行涡戳,所以這里的q一直是存儲的內(nèi)存引用,最終所有的a[i]()都是輸出 9?
不過脯倚,在es6中新增了let命令聲明變量渔彰,用法和var類似,不過let所聲明的變量推正,只在let命令所在的代碼塊有效果恍涂,for循環(huán)的計數(shù)器中就很適合let命令?
var a=[];?
for(let i = 0;i<10;i++){?
? let q = i;?
? a[i]=function(){console.log(q)}?
}?
a[6]()? ? //這里會輸出? 6? let聲明的變量僅在塊級作用域有效,所以這里的i只在本輪循環(huán)有效果植榕,每次循環(huán)的i其實都是一個新的變量