let命令
- let命令聲明的變量只在所在代碼塊內生效,適用于for循環(huán)中的變量栏尚。經(jīng)典的閉包問題如果用let來作為循環(huán)變量的話归苍,變量i是let聲明的,當前的i只在本輪循環(huán)有效麸恍,所以每一次循環(huán)的i其實都是一個新的變量灵巧,所以最后輸出的是6。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
JS的for循環(huán)有個特別之處抹沪,設置for循環(huán)變量的部分是一個父作用域刻肄,而其循環(huán)體是一個子作用域。
- let命令不存在變量提升融欧,變量在let命令定義語句之前使用的話敏弃,會報錯。
- let命令的暫時性死區(qū):(對應到c++是很容易理解的)
暫時性死區(qū)的本質就是噪馏,只要一進入當前作用域麦到,所要使用的變量就已經(jīng)存在了,但是不可獲取欠肾,只有等到聲明變量的那一行代碼出現(xiàn)瓶颠,才可以獲取和使用該變量。 - let不允許在相同作用域內刺桃,重復聲明同一個變量粹淋。
塊級作用域
我們知道ES5沒有塊級作用域,但這會帶來什么弊端虏肾?
- temp變量的使用廓啊,沒有塊級作用域意味著我們不能舒服得重用一個變量名。如下:
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
在function作用域中封豪,tmp因為變量提升谴轮,console語句打印的是未初始化的tmp。而我們實際只是想重用一下tmp這個變量名而已吹埠。立即調用表達式被let塊級作用域替換
- 塊級作用域與函數(shù)聲明,只對 ES6 的瀏覽器實現(xiàn)有效的三條規(guī)則
- 允許在塊級作用域內聲明函數(shù)第步。
- 函數(shù)聲明類似于var,即會提升到全局作用域或函數(shù)作用域的頭部缘琅。
- 同時粘都,函數(shù)聲明還會提升到所在的塊級作用域的頭部。
在瀏覽器的 ES6 環(huán)境中刷袍,塊級作用域內聲明的函數(shù)翩隧,行為類似于var聲明的變量。
const命令
- const聲明一個只讀的常量呻纹,且一聲明就要直接初始化堆生。只在聲明所在的塊級作用域內有效专缠。如果是對象指針,那么只是這個指針不可變淑仆,對象里面的屬性可以改變涝婉。
如果真的想將對象凍結,應該使用Object.freeze方法蔗怠。此處與vue的凍結對象讓其不再滿足響應式變換的方法一致墩弯。
聲明變量的方式:var,function寞射,let渔工,const,class怠惶,import(后四為ES6增加)
頂層對象的屬性
- ES5頂層對象的屬性與全局變量掛鉤涨缚,會帶來很多問題,很容易產(chǎn)生全局變量污染策治。ES6 為了改變這一點脓魏,一方面規(guī)定,為了保持兼容性通惫,var命令和function命令聲明的全局變量茂翔,依舊是頂層對象的屬性;但let命令履腋、const命令珊燎、class命令聲明的全局變量,不屬于頂層對象的屬性遵湖。