亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

怎么理解for循環中用let聲明的迭代變量每次是新的變量?

怎么理解for循環中用let聲明的迭代變量每次是新的變量?

ABOUTYOU 2018-09-05 14:34:31
背景最近在總結基礎知識,然后看了阮一峰老師的es6教程,其中談及let以及塊級作用域的時候,舉了一個經典的例子,代碼如下:var a = [];for (var i = 0; i < 10; i++) {  // 作用域a   a[i] = function () {    // 作用域b     console.log(i);   }; } a[6](); // 10因為es5不存在塊級作用域,所以迭代變量i泄露了,然后對于a數組內每一個函數內的i都是向上查詢作用域a的,所以結果是10。這個沒問題。下面的例子是用let來聲明迭代變量的var a = [];for (let i = 0; i < 10; i++) {   a[i] = function () {    console.log(i);   }; } a[6](); // 6老師是這樣解釋的上面代碼中,變量i是let聲明的,當前的i只在本輪循環有效,所以每一次循環的i其實都是一個新的變量,所以最后輸出的是6。疑問我想不通每一次循環的i其實都是一個新的變量這個過程是怎么樣的,如果我理解為每次迭代都是新的一個塊級作用域,那么迭代變量的迭代(i++)是如何傳遞給下一個塊級作用域呢?自知之明雖然我知道結果,也知道這樣的問題是轉牛角尖,就是好奇問問。希望各路英雄指點迷津。
查看完整描述

1 回答

?
慕妹3242003

TA貢獻1824條經驗 獲得超6個贊

這是在for語句中的var與let的差異:

for (let x...)的循環在每次迭代時都為x創建新的綁定

以下用代碼直接看會比較容易的理解。這個改進主要是為了要解決在for語句中的閉包結構的問題。

原來的使用var的代碼,與去糖(desugar)后來看它在執行時是這樣的模擬代碼:

//原來代碼for (var i = 0; i < 10; i++) { setTimeout(()=>console.log("i:",i), 1000); }
// 不需要加區塊符,因為區塊也不會影響var i;
i = 0;if (i < 10)
    setTimeout(()=>console.log("i:",i), 1000);
    i++;    if (i < 10)
        setTimeout(()=>console.log("i:",i), 1000);
        i++;//...

而使用了let后,會有塊級作用域的影響,原來的代碼與執行時的去糖模擬代碼如下:

// 原來代碼for (let i = 0; i < 10; i++) { setTimeout(()=>console.log("i:",i), 1000); }

// 用區塊符區分每次循環的語句// 每次for語句開始,i指定為一個全域刻度__status,這只是方便說明而已// __status會記錄for語句i最后的值{ let i;
  i = 0;
  __status = {i};
}
{ let {i} = __status;  if (i < 10)
      setTimeout(()=>console.log("i:",i), 1000);
      __status = {i};
}   
    { let {i} = __status;
      i++;      if (i < 10)
          setTimeout(()=>console.log("i:",i), 1000);
          __status = {i};
    }    //...


查看完整回答
反對 回復 2018-10-29
  • 1 回答
  • 0 關注
  • 1142 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號