前言
剛開始接觸 JavaScript 時,最先使用的宣告方式是 var
,慢慢的開始學會了 ES6 的 let
和 const
,所以就來筆記一下他們的不同
文章啟發於六角學院的 JS 學徒特訓班第三十八關
const vs let vs var
const
、 let
以及 var
都是用來宣告變數,他們都是宣告變數,為什麼明明有了 var
還要增加 const
和 let
呢?
其實就是為了修正 var
的一些缺點
作用域(汙染全域)
var
屬於作用域屬於函式作用域,意思就是var
變數的範圍在 function
作用範圍(scope)又稱作用域,指的是變數或常數的定義與語句可見(被存取得到)的範圍
1 | function fun() { |
從上面例子來看,因為屬於函式作用域(function scope),我們不能從 function
內拿到 a
值 ,也就是說只能在函式內才能使用
而 const
和 let
屬於區塊作用域,區塊如 if
、for
、switch
、while
等等有使用區塊({ }
)語句
1 | function fun() { |
以 funtion
一樣也是會出現錯誤,但我們使用 if
發現用 var
宣告的 c
是可以取到值的,而 b
則不行
再來我們使用「開發人員工具」輸入 window
去搜尋,會發現 c
竟然變成全域變數了,由此得知使用 const
和 let
可以確保不會污染到全域
重複宣告
我們來看看以下問題答案是什麼
1 | //範例一 |
- 範例一 :
var
是允許重複宣告的也可以重新賦值,而且即使在同一個作用域,同樣名稱的變數也允許重複宣告,所以a
答案就是 234 - 範例二 :
let
與var
的不同點在於不能重複宣告,所以b
答案是 3 ,而c
的答案則是Identifier 'c' has already been declared
- 範例三 :
const
則是不能重複宣告也不能重新賦值,只能用來宣告常數(在 ES6 中的定義是constant variable 固定的變數),所以d
的答案是Assignment to constant variable.
const 的特性
const
除了以上特性外,對於物件和陣列來說若只是傳參考也可以使用,另外還有一點就是必須一定要有值,對於var
和 let
宣告變數可以不賦予值,但 const
不賦值就會出錯
1 | const a; //Missing initializer in const declaration |
其實可以這樣想你都要宣告一個變數了怎麼可能還不賦予值對吧XDD,而 const 又不能更動值,所以邏輯上 const 就一定要有值囉
關於
const
使用在物件或者陣列上,參考這篇 文章
Hoisting 變量提升
使用 var
宣告變數時,會有一種特性
1 | console.log(a); //undefined |
答案竟然不是 a is not defined
而是 undefined
,這是因為Hoisting的關係
var
有提升,那 const
和 let
呢?
console.log(b); //ReferenceError: b is not defined
let b = 123;
是 b is not defined
耶,這樣說明是不是代表沒有提升囉? 哦不不不,哦不不不,我看你是 too young too simple(誤
其實是 const
和 let
也是存在變量提升的,但因為 暫時死區(Temporal Dead Zone,TDZ) 的關係,才會感覺沒有提升
TDZ : 如宣告變數前存取該變數會產生
ReferenceError
錯誤,這就是稱為 暫時死區 (Temporal Dead Zone)
總結
最後簡單整理一個表格提供參考,也可以知道何時該用什麼方法宣告
var | let | const | |
---|---|---|---|
作用域(範圍) | 函式 | 區塊 | 區塊 |
重複宣告 | 可 | 不可 | 不可 |
重新賦值 | 可 | 可 | 不可 |
變量提升 | 有 | 有 | 有 |