窿冯。
for
循環(huán)的計數器,就很合適使用let
命令确徙。
for (let i = 0; i < 10; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined
上面代碼中醒串,計數器i
只在for
循環(huán)體內有效,在循環(huán)體外引用就會報錯鄙皇。
下面的代碼如果使用var
芜赌,最后輸出的是10
。
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
上面代碼中育苟,變量i
是var
命令聲明的较鼓,在全局范圍內都有效,所以全局只有一個變量i
违柏。每一次循環(huán)博烂,變量i
的值都會發(fā)生改變,而循環(huán)內被賦給數組a
的函數內部的console.log(i)
漱竖,里面的i
指向的就是全局的i
禽篱。也就是說,所有數組a
的成員里面的i
馍惹,指向的都是同一個i
躺率,導致運行時輸出的是最后一輪的i
的值玛界,也就是 10。
如果使用let
悼吱,聲明的變量僅在塊級作用域內有效慎框,最后輸出的是 6。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
上面代碼中后添,變量i
是let
聲明的笨枯,當前的i
只在本輪循環(huán)有效,所以每一次循環(huán)的i
其實都是一個新的變量遇西,所以最后輸出的是6
馅精。你可能會問,如果每一輪循環(huán)的變量i
都是重新聲明的粱檀,那它怎么知道上一輪循環(huán)的值洲敢,從而計算出本輪循環(huán)的值?這是因為 JavaScript 引擎內部會記住上一輪循環(huán)的值茄蚯,初始化本輪的變量i
時压彭,就在上一輪循環(huán)的基礎上進行計算。
另外渗常,for
循環(huán)還有一個特別之處硬猫,就是設置循環(huán)變量的那部分是一個父作用域抢韭,而循環(huán)體內部是一個單獨的子作用域囱井。
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
上面代碼正確運行犁功,輸出了 3 次abc
。這表明函數內部的變量i
與循環(huán)變量i
不在同一個作用域尸执,有各自單獨的作用域家凯。