JavaScript中 var, let, const 之間的差異

宣告

我們會藉由 var, let, const 做宣告,這三個即是在 Javascript 內的保留字。

而早期只有 var 來宣告,但在 ES6 之後就加入了 let 以及 const。

宣告的重要性

如果沒有宣告變數, 有可能導致無法預測的結果。

在 ECMAScript 5 中的嚴格模式(strict model),

如果在函數中,給一個沒有經過宣告的函數,賦予值將導致錯誤。

那什麼是嚴格模式,未來會將有一篇特別提到嚴格模式。

var

用來宣告變數同時間,賦予一個初始值(非強制性)。非強制性指的是什麼呢?

舉個例子:

1
var a;

我們可以藉由 var a 來宣告一個 a 變數,但我們不一定要給 a 變數任何初始值。

let

用來宣告一個變數,而這個變數只能用於目前區塊(block),只要跳脫出 block 就不行使用,

而初始值可以選擇是否需要設定。

1
2
3
4
for (let i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);

前面迴圈分別得到 0, 1, 2, 3, 4 ;

而在 Block 外的 console.log(i),其中的 i 已經跳脫出 Block Scope,

所以會得到 Uncaught ReferenceError: i is not defined

const

用來宣告常數(Constants),它與 let 宣告相似,也具有區塊範圍,

然而常數不能重複指定它的值,也不能重複做宣告。

所以對於 const 宣告時,不適合不給初始值,因為常數不能變,

所以宣告的同時就要給定值,要不然藉由 const 宣告出來的東西就沒意義。

差異

  1. 對於宣告而言:

var 宣告後的變數,是可以重複被宣告的;

但 let 跟 const 是不能重複被宣告。

1
2
var feeling = "happy";
var feeling = "unhappy";

var 可以重複被宣告

1
2
let feeling = "happy";
let feeling = "unhappy";

而 let 不可以重複被宣告。

但 let 可以重新賦予值:

1
2
let feeling = "happy";
feeling = "unhappy";
  1. 對於作用的範圍而言:

var 定義出來的是變數全域變數,也是 function scope,

主要是針對在 function 內用 var 定義出來的變數,跳脫出 Function 後,就會沒有作用;

對於 let 跟 const 都是 Block Scope,跳脫出 Block 後,就會沒有作用。

例子 1:

1
2
var feeling = "happy";
window.feeling; // "happy"

會得到 happy。

1
2
let feeling = "happy";
window.feeling; // "undefined"

會得到 undefined。

例子 2:

1
2
3
4
for (var i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);

前面迴圈分別得到 0, 1, 2, 3, 4 ;

而在 Block 外的 console.log(i)會得到 4。

1
2
3
4
for (let i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);

前面迴圈分別得到 0, 1, 2, 3, 4 ;

而在 Block 外的 console.log(i),其中的 i 已經跳脫出 Block Scope,

所以會得到 Uncaught ReferenceError: i is not defined

例子 3:

1
2
3
4
5
6
function num() {
for (var i = 0; i < 5; i++) {
console.log(i);
}
}
console.log(i);

會得到 Uncaught ReferenceError: i is not defined,因為 var 定義的變數 i,

已經跳脫出 Function Scope。

而在 Block 外的 console.log(i)會得到 4。

  1. 對於變數提升而言:

主要會藉由新的一篇詳細介紹什麼是變數提升,在這邊只會比較有什麼差異:

var 宣告的變數,會將初始化的值定義成 undefined,

所以當宣告前就使用變數,只會得到 undefined,而不會跳出錯誤訊息;

但 let 與 const 所宣告的變數,對於變數提升而言,不會做初始化,

所以這些變數會進入暫時死區(Temporal Dead Zone,簡稱 TDZ),

所以當宣告前就使用變數,就會出現錯誤訊息。

總結

let 跟 const 大多都是一樣的,所以上面的例子都是 let 跟 var 的差別;

然而,let 是針對變數宣告,而 const 是針對常數做宣告,

所以 let 可以重新賦予值,但 const 不行。

但對於賦予值的定義是不能改變當變數是原生值的時候,例如:字串、數字…等。

如果變數是物件,仍可以改變。

1
2
const feeling = { today: "happy" };
feeling.today = "unhappy";

這樣 feeling 就會變成 today: “unhappy”


參考資料:

MDN - var

MDN - let

MDN - const