JS 趴趴走 - ES6 const & let

前言

剛開始接觸 JavaScript 時,最先使用的宣告方式是 var,慢慢的開始學會了 ES6 的 letconst ,所以就來筆記一下他們的不同

文章啟發於六角學院的 JS 學徒特訓班第三十八關

const vs let vs var

constlet 以及 var 都是用來宣告變數,他們都是宣告變數,為什麼明明有了 var 還要增加 constlet 呢?
其實就是為了修正 var 的一些缺點

作用域(汙染全域)

var 屬於作用域屬於函式作用域,意思就是var 變數的範圍在 function

作用範圍(scope)又稱作用域,指的是變數或常數的定義與語句可見(被存取得到)的範圍

1
2
3
4
function fun() {
var a = 100;
}
console.log(a); //ReferenceError: a is not defined

從上面例子來看,因為屬於函式作用域(function scope),我們不能從 function 內拿到 a 值 ,也就是說只能在函式內才能使用

constlet 屬於區塊作用域,區塊如 ifforswitchwhile 等等有使用區塊({ })語句

1
2
3
4
5
6
7
8
9
10
11
 function fun() {
let a = 100;
}
console.log(a); //ReferenceError: a is not defined

if (true) {
const b = '我不能來出來';
var c = '我可以拿出來';
}
console.log(c); //我可以拿出來
console.log(b); //ReferenceError: b is not defined

funtion 一樣也是會出現錯誤,但我們使用 if 發現用 var 宣告的 c 是可以取到值的,而 b 則不行

再來我們使用「開發人員工具」輸入 window 去搜尋,會發現 c 竟然變成全域變數了,由此得知使用 constlet 可以確保不會污染到全域

重複宣告

我們來看看以下問題答案是什麼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//範例一
var a = 10;
a = 123;
var a = 234;

//範例二
let b = 1;
b = 3;

let c = 1;
let c = 2;

//範例三
const d = 3;
d = 4;
  • 範例一 : var 是允許重複宣告的也可以重新賦值,而且即使在同一個作用域,同樣名稱的變數也允許重複宣告,所以 a 答案就是 234
  • 範例二 : letvar 的不同點在於不能重複宣告,所以 b 答案是 3 ,而 c 的答案則是 Identifier 'c' has already been declared
  • 範例三 : const 則是不能重複宣告也不能重新賦值,只能用來宣告常數(在 ES6 中的定義是constant variable 固定的變數),所以 d 的答案是 Assignment to constant variable.

const 的特性

const除了以上特性外,對於物件和陣列來說若只是傳參考也可以使用,另外還有一點就是必須一定要有值,對於varlet 宣告變數可以不賦予值,但 const 不賦值就會出錯

1
const a;   //Missing initializer in const declaration

其實可以這樣想你都要宣告一個變數了怎麼可能還不賦予值對吧XDD,而 const 又不能更動值,所以邏輯上 const 就一定要有值囉

關於const使用在物件或者陣列上,參考這篇 文章

Hoisting 變量提升

使用 var 宣告變數時,會有一種特性

1
2
console.log(a);  //undefined
var a = 10;

答案竟然不是 a is not defined 而是 undefined,這是因為Hoisting的關係

var有提升,那 constlet呢?

console.log(b);  //ReferenceError: b is not defined
let b = 123;

b is not defined耶,這樣說明是不是代表沒有提升囉? 哦不不不,哦不不不,我看你是 too young too simple(誤

其實是 constlet 也是存在變量提升的,但因為 暫時死區(Temporal Dead Zone,TDZ) 的關係,才會感覺沒有提升

TDZ : 如宣告變數前存取該變數會產生 ReferenceError 錯誤,這就是稱為 暫時死區 (Temporal Dead Zone)

總結

最後簡單整理一個表格提供參考,也可以知道何時該用什麼方法宣告

var let const
作用域(範圍) 函式 區塊 區塊
重複宣告 不可 不可
重新賦值 不可
變量提升