在 let 出現之前,for 迴圈定義的迭代變數會滲透到迴圈體外部:for (var i = 0; i < 5; ++i)
console.log(i); // 5
改成使用 let 之後,這個問題就消失了,因為迭代變數的作用域僅限於 for 迴圈塊內部:
for (let i = 0; i < 5; ++i)
console.log(i); // referenceerror: i 沒有定義
在使用 var 的時候,最常見的問題就是對迭代變數的奇特宣告和修改:
for (var i = 0; i < 5; ++i)
// 你可能以為會輸出 0、1、2、3、4
// 實際上會輸出 5、5、5、5、5
之所以會這樣,是因為在退出迴圈時,迭代變數儲存的是導致迴圈退出的值:5。在之後執行超時
邏輯時,所有的 i 都是同乙個變數,因而輸出的都是同乙個最終值。
而在使用 let 宣告迭代變數時,j**ascript 引擎在後台會為每個迭代迴圈宣告乙個新的迭代變數。
每個 settimeout 引用的都是不同的變數例項,所以 console.log 輸出的是我們期望的值,也就是循
環執行過程中每個迭代變數的值。
for (let i = 0; i < 5; ++i)
// 會輸出 0、1、2、3、4
引自:3.3.3 【const宣告】
這裡提到了let生命迭代變數時,js引擎會在後台為每個迭代迴圈宣告乙個新的變數,根據怎麼理解for迴圈中用let宣告的迭代變數每次是新的變數?這篇文章中的介紹,
在使用var定義變數i時,
for (var i = 0; i < 5; ++i)
在去糖(desugar)後執行的模擬**為:
// 不需要加區塊符,因為區塊也不會影響
var i;
i=0;
if(i<5)
settimeout(() => console.log(i), 0);
i++;
if(i<5)
settimeout(() => console.log(i), 0);
//...i++;
在使用let定義變數i時,
// 用區塊符區分每次迴圈的語句
// 每次for語句開始,i指定為乙個全域刻度__status,這只是方便說明而已
// __status會記錄for語句i最後的值;}
= __status;
if (i < 10)
settimeout(()=>console.log(i), 0);
__status = ;
}
= __status;
i++;
if (i < 10)
settimeout(()=>console.log(i), 0);
__status = ;
}//...
let變數宣告總結
let命令有四大主要特性 存在塊級作用域,沒有變數提公升,暫時性死區,不允許重複宣告。記憶 塊作沒變,暫死不重 這都是和es5的var變數特性相反的。var的作用域是函式級的。let命令宣告的變數只在其塊級作用域中有效,就是 中。console.log a 出錯 not defined consol...
使用let宣告變數
es5宣告變數的問題 1.全域性變數掛載到全域性物件 全域性物件成員汙染問題。let宣告的變數不會掛載到全域性物件。2.允許重複的變數宣告,導致變數被覆蓋。let宣告的變數不允許當前作用域範圍內重複宣告。3.變數提公升 怪異的資料訪問,閉包問題。使用let不會有變數提公升,因此,不能在定義變數之前使...
for迴圈中let和var的區別
先看2段 使用var宣告,得到3個3 var a for var i 0 i 3 i a 0 3a 1 3a 2 3 使用let宣告,得到0,1,2 var a for let i 0 i 3 i a 0 0a 1 1a 2 2這是為什麼呢?首先要知道var 宣告作用域是函式作用域,let宣告的作用...