ES6之let與const

思維導圖
JavaScript/">JavaScript共包含三個部分: ECMAScript、DOM和BOM ,而我們今天開始所要講的ES6的全稱就是ECMAScript6,它是2015年釋出的ECMAScript標準,故又被稱之為ECMAScript2015。而後每年都會更新一個新版本,並以該年份置於其後作為標識,而這些從2015年開始的ECMAScript版本都被統稱為ES6。
ES6相對之前版本增加了很多新的特性,但是也有很多都只是 語法糖 ,也就是說實現功能和之前一樣,只是語法更簡潔了而已(如箭頭函式、類)。這些新特性新語法給我們開發帶來了很多便利,提高了工作效率和降低了維護成本。遺憾的是,現代瀏覽器對ES6相容參差不齊,所以導致很多人雖然想用但是不敢用。不過幸虧有了像Babel這樣優秀的編譯工具,能將ES6語法編譯成現代瀏覽器能識別的ES6之前版本,這樣我們又可以輕鬆愉快地使用它了。
接下來,就讓我來為大家一步步地開啟這扇通往ES6的大門吧!
一、let——變數宣告
在ES6之前,我們是使用 var
來宣告變數,那麼我們就來簡單說說 var
和 let
之間到底有什麼區別。
1. 塊級作用域
① var
宣告的變數不是塊級作用域,所以程式碼塊之外能訪問程式碼塊中的變數。
{// 程式碼塊 var a = 0;// 全域性變數,外部可訪問 } console.log(a);// 0
② let
宣告的變數是塊級作用域,所以程式碼塊之外無法訪問程式碼塊中的變數。
{// 程式碼塊 let a = 0;// 區域性變數,外部可訪問 } console.log(a);// 報錯
2. 暫時性死區
① var
宣告的變數會進行變數提升,也就是說,該變數宣告總會被提升到作用域最頂部。
{ a = 0; var a; } console.log(a);// 0
變數 a
的作用域為全域性,故以上程式碼其實相當於下面程式碼:
var a;// 變數提升 { a = 0; } console.log(a);// 0
然後再看下面這個例子:
console.log(a);// undefined { a = 0; var a; }
你會發現即使最上面沒有宣告過變數 a
,我們去列印它也並不會報錯,這是因為 var a;
會提升到 console.log(a);
之前。
② let
比較霸道,用它宣告的變數必須在其作用域內並在宣告之後使用,即使全域性已經用 var
宣告過該變數也不行。
{ a = 0;// 在宣告前賦值會報錯 let a; }
// 在宣告前使用就會報錯,不管程式碼塊外面是否宣告過這個變數 var a; { a = 0;// 報錯 let a; }
後面這個例子可以看到,雖然全域性已經宣告過了變數 a
,本來程式碼塊中是可以正常訪問到這個變數的,但因為這個程式碼塊中用 let
又聲明瞭一次變數 a
,因此這個程式碼塊就像一片 “死區” 一樣,無法訪問外部變數,當然這只是針對這個用 let
宣告的 a
來說是 “死區” ,若是用 var
宣告的其他變數則照樣可以訪問外部變數。這種用 let
繫結整個程式碼塊的“霸道行為”,在語法上被稱之為 “暫時性死區” 。
其實,按照我個人理解,我們完全可以不用去理會這個 “暫時性死區” 的具體含義,只需知道的是,不管什麼情況, let
宣告的變數,必須在其宣告之後才能使用 。
3. 不能重複宣告
① var
比較開放, 同一作用域內, 同一變數可以宣告多次,並不會報錯。
var a = 0; var a = 1; console.log(a);// 1
以上程式碼相當於:
var a; a = 0; a = 1; console.log(a);// 1
② let
比較專一, 同一作用域內, 同一變數只能宣告一次,否則就會報錯。
let a = 0; let a = 1;// 報錯
let a = 0; var a = 1;// 變數提升,報錯
var a = 1; let a = 0;// 報錯
let a = 0; { var a = 1;// 變數提升,報錯 }
但是注意以下情況是正常的:
let a = 0; { let a = 1;// 無變數提升,是區域性變數,與全域性宣告的變數不在同一個作用域 } console.log(a);// 0
var a = 0; { let a = 1;// 無變數提升,是區域性變數,與全域性宣告的變數不在同一個作用域 } console.log(a);// 0
其實只需記住一點: 在同一作用域中判斷 ,這樣就能很好地判斷是否重複聲明瞭。
二、const——常量宣告
const
與 let
很像,所以本文也是直接把他們放在一起說,它幾乎與 let
一樣,只不過它宣告的是常量, 常量值不能更改 ,且必須 在宣告時賦值 。
1. 宣告常量
既然是常量,當然是不可更改的。
const a = 0; a = 1;// 報錯,常量值不可更改
但是要注意下面這種情況是可以的:
const a = []; a.push(1); console.log(a)// [1]
這是為什麼呢?不是說常量值不可更改嗎?可現在為什麼又把空陣列變成了 [1]
呢?
其實道理很簡單,我們開始賦值給常量 a
的只是陣列的引用而已(就是陣列的儲存地址),當我們去修改該陣列時,這個引用並不會發生改變。 這就像是你給家裡房子裝修佈置了一下,但是家庭地址並沒有變,可是如果你直接換了一套新房,那可就不一樣了。
const a = []; a = [1];// 報錯,引用不可更改
這是重新賦值了新的陣列,引用發生改變,所以就會報錯。
2. 具有let相同特性
塊級作用域、 先聲明後使用 和 不能重複宣告 這些特性對於 const
一樣適用,因此不再贅述。
但需要注意的是,用 var
或 let
宣告過的變數,再宣告相同名稱常量也算是重複宣告。
var a; const a = 0;// 報錯
let a; const a = 0;// 報錯
const a = 0; var a;// 報錯
const a = 0; let a;// 報錯
3. 宣告時必須賦值
const a;// 報錯
let
宣告的是變數,所以可以先聲明後賦值,可 const
不一樣,它宣告的時常量,你在宣告的同時就必須給其賦值,否則它不會給你好心地預設給你賦個 undefined
,而是毫不留情地給你報錯!
重點總結
① let
在程式碼塊中宣告的變數為區域性變數
② let
宣告的變數,必須在其宣告之後才能使用
③ let
在同一作用域內不可重複宣告同一變數,包括 var
或 const
宣告過的也不行
④ const
宣告常量,不可更改,但如果是引用型別常量,則可以修改其內部資料
⑤ const
具有 let
相同特性(包括①②③所有特性)
⑥ const
在宣告常量時必須同時進行賦值