關(guān)于let和var作用域不同導(dǎo)致在異步操作中的不同表現(xiàn)

今天在寫代碼時遇到了個奇怪的問題。

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

輸出為

10
10
10
10
...

這是個在JavaScript中十分常見的異步問題揍鸟,出現(xiàn)這種輸出的根本原因在于:

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

中var i實(shí)際上是將i掛載到了全局變量上鳄厌,當(dāng)settimeout的回調(diào)函數(shù)執(zhí)行時借宵,i已經(jīng)被for循環(huán)累加到了10弧轧,讀取并輸出的自然就是十個10了。
如果想依次輸出0~9該如何呢斑芜?在es5之前肩刃,有個取巧的方法,就是將i包裹在一個閉包中杏头,將i作為一個函數(shù)的私有變量保存起來盈包,這樣每次settimeout的回調(diào)函數(shù)就可以輸出屬于自己的i了。

但 let 指令可以幫助我們完美的解決這個問題醇王,將上述代碼做一下改造呢燥。

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

可以看出,與最初的代碼唯一的不同寓娩,就是將 var i= 0 改為了叛氨,let i = 0
測試一下,輸出為

0
1
2
3
..

為什么改了i的聲明方式輸出結(jié)果就會截然不同了呢棘伴?
那就要從var與let的不同點(diǎn)說起寞埠。
let 與 var 最大的區(qū)別就在于,var 與let 生命的變量的作用域不同焊夸。
var 是以函數(shù)作為自己的作用域仁连。
而 let 則是以{ }為作用域。
具體是什么意思呢阱穗?就以上邊的代碼為例饭冬,for循環(huán)展開后等價于

{
    let i = 0;
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
{
    let i = 1;
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
{
    let i = 2;
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
...

而使用var時則是

var i = 0;
i++;
i++;
i++;
...

{
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
{
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
{
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
...

這么看是不是就直觀了許多颇象?使用let生命的變量伍伤,作用域只存在于一個{}之間,所以for循環(huán)一共循環(huán)幾遍遣钳,就會有幾個{},每一個{}都會有自己獨(dú)有的 i 麦乞。
而var則是以函數(shù)為單位蕴茴,如果沒有外層函數(shù)就會掛載到全局變量上,所有的{}都會共有1個i姐直,自然就會輸出同樣的值了倦淀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市声畏,隨后出現(xiàn)的幾起案子撞叽,更是在濱河造成了極大的恐慌姻成,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,294評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愿棋,死亡現(xiàn)場離奇詭異科展,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)糠雨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評論 3 385
  • 文/潘曉璐 我一進(jìn)店門才睹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甘邀,你說我怎么就攤上這事琅攘。” “怎么了松邪?”我有些...
    開封第一講書人閱讀 157,790評論 0 348
  • 文/不壞的土叔 我叫張陵坞琴,是天一觀的道長。 經(jīng)常有香客問我逗抑,道長剧辐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,595評論 1 284
  • 正文 為了忘掉前任锋八,我火速辦了婚禮浙于,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挟纱。我一直安慰自己羞酗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,718評論 6 386
  • 文/花漫 我一把揭開白布紊服。 她就那樣靜靜地躺著檀轨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪欺嗤。 梳的紋絲不亂的頭發(fā)上参萄,一...
    開封第一講書人閱讀 49,906評論 1 290
  • 那天,我揣著相機(jī)與錄音煎饼,去河邊找鬼讹挎。 笑死,一個胖子當(dāng)著我的面吹牛吆玖,可吹牛的內(nèi)容都是我干的筒溃。 我是一名探鬼主播,決...
    沈念sama閱讀 39,053評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼沾乘,長吁一口氣:“原來是場噩夢啊……” “哼怜奖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起翅阵,我...
    開封第一講書人閱讀 37,797評論 0 268
  • 序言:老撾萬榮一對情侶失蹤歪玲,失蹤者是張志新(化名)和其女友劉穎迁央,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滥崩,經(jīng)...
    沈念sama閱讀 44,250評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岖圈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,570評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了夭委。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幅狮。...
    茶點(diǎn)故事閱讀 38,711評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖株灸,靈堂內(nèi)的尸體忽然破棺而出崇摄,到底是詐尸還是另有隱情,我是刑警寧澤慌烧,帶...
    沈念sama閱讀 34,388評論 4 332
  • 正文 年R本政府宣布逐抑,位于F島的核電站,受9級特大地震影響屹蚊,放射性物質(zhì)發(fā)生泄漏厕氨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,018評論 3 316
  • 文/蒙蒙 一汹粤、第九天 我趴在偏房一處隱蔽的房頂上張望命斧。 院中可真熱鬧,春花似錦嘱兼、人聲如沸国葬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汇四。三九已至,卻和暖如春踢涌,著一層夾襖步出監(jiān)牢的瞬間通孽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評論 1 266
  • 我被黑心中介騙來泰國打工睁壁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留背苦,地道東北人。 一個月前我還...
    沈念sama閱讀 46,461評論 2 360
  • 正文 我出身青樓潘明,卻偏偏與公主長得像糠惫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子钉疫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,595評論 2 350

推薦閱讀更多精彩內(nèi)容