- 在for循環(huán)中使用var
for(var i = 0;i<2;i++){
setTimeout(()=>{console.log(i)})
}
上面的代碼輸出兩個(gè)2,原因是for循環(huán)屬于同步,setTimeout屬于異步肴盏,同步代碼執(zhí)行完才會去執(zhí)行異步,也就是上面代碼每次循環(huán)都會項(xiàng)任務(wù)隊(duì)列里加一個(gè)定時(shí)器帽衙,等for循環(huán)結(jié)束后開始執(zhí)行菜皂,這時(shí)候的i是2,所以會打印出兩個(gè)2厉萝。在for循環(huán)中用var就是一個(gè)全局的i恍飘,所以每次會被后面的給替換
- 在for循環(huán)中使用let
for(let i = 0;i<2;i++){
setTimeout(()=>{console.log(i)})
}
2中的代碼最后打印出的是0,1。因?yàn)閒or循環(huán)中使用let循環(huán)幾次就會生成幾個(gè)i谴垫,也就是說在每次進(jìn)入循環(huán)的時(shí)候都會把之前的i賦值給一個(gè)新的i
- 在for的表達(dá)式中使用異步
需要提前說明的知識
let i = 0,1
//等價(jià)于
let i = (0,1)
上面的代碼結(jié)果都是1章母,對于逗號表達(dá)式如果你有一連串的操作,那么這個(gè)表達(dá)式的值就是最后一個(gè)
典型例題
for(let i = (setTimeout(()=>{console.log(i)},233),0);
i<2;
i++
){
console.log(i)
}
上面的setTimeout里的i又是什么翩剪?
答:0乳怎;
解釋:
2中說了每次進(jìn)入循環(huán)前都會生成一個(gè)新的i,這個(gè)i就是在初始化表達(dá)式后肢专,條件表達(dá)式前生成的舞肆,也就是說在判斷這個(gè)i的值之前就已經(jīng)生成了一個(gè)新的i了焦辅,這個(gè)新的i要不就是初始值要不就是上一次循環(huán)的i的值博杖,再次以2中的代碼來解釋,就相當(dāng)于
for(let i = 0;let i = _i
, i<2;i++){
setTimeout(()=>{console.log(i)})
}
上面的代碼筷登,一開始i=0剃根,然后把這個(gè)0賦值給一個(gè)新的i,再去判斷i是否小于2前方,如果小于2就進(jìn)入循環(huán),得到0惠险,然后把這個(gè)0進(jìn)行++得到一個(gè)1苗傅,再次把這個(gè)1賦值給一個(gè)新的i,判斷是否小于2班巩,小于2進(jìn)入循環(huán)得到1渣慕,然后1在++得到一個(gè)2,把這個(gè)2賦值給一個(gè)新的i,這個(gè)時(shí)候不小于2退出循環(huán)
所以這個(gè)典型例題里面的初始化表達(dá)式的i跟后面的i沒有關(guān)系逊桦,只是它的值會復(fù)制給后面的i眨猎,所以最后還是0