一項新技術的出現肯定是為瞭解決一些問題,那麼ES6的出現主要是解決了哪些問題?它的出現給我們帶來了什麼便利?當它沒有出現的時候,某些問題怎麼處理?ES6的方法和以前的方法比較又有什麼不同呢?根據提出的這些問題,我開始了ES6學習之旅。 ES6是在ES5的基礎上對語法進行了修正以及添加了一些新的功能, ...
一項新技術的出現肯定是為瞭解決一些問題,那麼ES6的出現主要是解決了哪些問題?它的出現給我們帶來了什麼便利?當它沒有出現的時候,某些問題怎麼處理?ES6的方法和以前的方法比較又有什麼不同呢?根據提出的這些問題,我開始了ES6學習之旅。
ES6是在ES5的基礎上對語法進行了修正以及添加了一些新的功能, 具體修正了哪些語法與添加了哪些新的功能,那就開始學習吧。
let
ES6新增加了let命令,用於變數聲明,與var的用法類似,不同的是所聲明的變數只在let命令所在的代碼塊內有效。
{ let a = 10; let b = 1; } a // ReferenceError b // 1View Code
以下代碼會輸出10,因為 i 是var聲明的,在全局範圍內都有效。所以每一次迴圈,新的 i 值都會覆蓋舊值,導致最後輸出的是最後一輪的 i 的值。如果 i 是let聲明的,該變數僅在塊級作用域內有效,最後輸出的會是 6。
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10View Code
我們都知道ES5中的變數會提升到頂部,所以可以先調用後聲明,之所以可以是因為是var聲明的,而let聲明的變數不會提升,所以必須先聲明才可以調用。還有,只要let命令存在於塊級作用域內,它所聲明的變數就"綁定"了這個區域,不再受外部的影響。例如如下代碼:
var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; }View Code
在塊級作用域內使用let又聲明變數tmp,那麼這個變數就不會再受外部變數的影響,而let聲明的變數無法提升,所以在沒有聲明前調用就會出錯。
總之,在代碼塊內,在沒有使用let聲明變數之前,該變數都是不可用的,這在ES6的語法上稱為"暫時性死區","暫時性死區"的出現意味著typeof不再是一個百分之百安全的操作。
typeof x; // ReferenceError let x; typeof y // "undefined"View Code
在沒有聲明x前,使用typeof檢測x的類型就會報錯,而檢測一個沒有被聲明的變數反而不會報錯。
let還不允許在相同作用域內,重覆聲明同一個變數,如下情況都會報錯:
// 報錯 function () { let a = 10; var a = 1; } // 報錯 function () { let a = 10; let a = 1; }View Code
所以,在函數內重新聲明變數也是會報錯的:
function func(arg) { let arg; // 報錯 }View Code
在不同的作用域里重新聲明變數是可以的:
function func(arg) { { let arg; // 不報錯 } }View Code
const
const聲明一個只讀的常量,一旦聲明,常量的值就不能改變,因為無法改變,所以聲明變數的時候就需要立即初始化變數,不能留到以後賦值。const的作用域與let命令相同:只在聲明所在的塊級作用域內有效,而且變數也是無法提升的,也存在"暫時性死區",只能聲明後再調用,也不可以重覆聲明。
對於複雜類型的變數,變數名不指向數據,而是指向數據所在的地址,const命令只是保證變數名指向的地址不變,並不保證該地址的數據不變,所以將一個對象聲明為常量必須非常小心。
const foo = {}; foo.prop = 123; foo.prop // 123 foo = {}; // TypeError: "foo" is read-onlyView Code
常量foo儲存的是一個地址,這個地址指向一個對象。不可變的只是這個地址,即不能把foo指向另一個地址,但對象本身是可變的,所以依然可以為其添加新屬性。
如果想將對象凍結,可以使用Object.freeze方法,一旦凍結,就無法為其添加新的屬性,嚴格模式下會報錯
const foo = Object.freeze({}); // 常規模式時,下麵一行不起作用; // 嚴格模式時,該行會報錯 foo.prop = 123;View Code
ES5 只有兩種聲明變數的方法:var命令和function命令。 ES6 除了添加let和const命令,還有另外兩種聲明變數的方法:import命令和class命令,以後再學習這兩種聲明變數的方法。