JavaScript - ES6 - 變數
在 ES6 中多了兩種變數的宣告方式,let
與 const
,其最大的目的在於盡量避免汙染到全域,原因在於載入多個模組或進行多人協作時,如果遇到相同名稱的全域變數就會發生衝突,也減少了程式的靈活性
window 與 var
在 ES6 以前,都使用 var
來進行變數的宣告,而切分 var
有效範圍的最小單位是 函式 function,所以在 function
外使用 var
宣告的變數都會成為全域變數,也就是 最高級物件 window
的屬性
1 | var a = 0; |
let 與 var
與 var
不同的是,let
是一個 區塊 block
變數,block
意指 大括號 { }
, 也就是說切分 let 有效範圍的最小單位是 大括號 { }
,且使用 let 宣告的全域變數不會成為全域物件 window
的屬性
同上範例,我們將 var
都改成 let
1 | let a = 0; |
let 與 for 的用法
如下範例,我們要讓每一個 li
被點擊時都能顯示自己的數字
1 | <ul class="list"> |
1 | for (var i = 0; i < 2; i++){ |
但結果並不如預期,在點擊每個 li
都會是 4
,因為這裡的變數 i
使用 var
來宣告,所以是全域變數,當跑完 for 迴圈的時候,所有 console.log(i + 1)
中的 i
都會被全域的 i = 3
取代
如果將上述範例的 var
改成 let
1 | for (let i = 0; i < 2; i++){ |
改成 let
來宣告的結果會如預期一樣,點擊每個 li
都是自己的數字,因為變數 i
並不會成為全域變數,所以 console.log(i + 1)
中的 i
都會是迴圈執行時當下取得的值
1 | for (let i = 0; i < 2; i++){ |
改成 let 來宣告的結果會如預期一樣,點擊每個 li 都是自己的數字,因為變數 i 並不會成為全域變數,所以 console.log(i + 1) 中的 i 都會是迴圈執行時當下取得的值
const
使用
const
宣告的變數又稱為 “常數” 或 “唯讀變數”宣告完的變數無法再進行修改
1
2
3const a = 1;
a = 2;
console.log(a); // 錯誤但使用
const
宣告的 物件{ }
和 陣列[]
依然可以修改其內容,因為物件型別是 “傳址”pass by reference
1
2
3
4
5const obj = {
url: 'a'
};
obj.url = 'b';
console.log(obj.url); // b如果要使宣告的物件連屬性也無法修改,可以使用
Object.freeze()
來將物件凍結1
2
3
4
5
6const obj = {
url: 'a'
};
Object.freeze(obj);
obj.url = b;
console.log(obj.url); // a
let 與 const 的注意事項
ES6 變數的宣告與以往使用 var
有一些性質上的不同,以下一一介紹
不會向上提升 Hoisting,從宣告的那一行開始成立
1
2
3
4
5
6
7
8var d;
console.log(a); // undefined
console.log(b); // ReferenceError
console.log(c); // ReferenceError
console.log(d); // undefined
var a = 1;
let b = 2;
const c = 3;同一個 “區塊”
block
內不能重複命名1
2
3
4
5
6
7
8var a = 1;
var a = 2;
console.log(a); // 2
let b = 1;
let b = 2; // SyntaxError
const c = 1;
const c = 2; // SyntaxError在全域宣告的變數不會成為最高級物件
window
的屬性1
2
3
4
5
6var a = 1;
let b = 2;
const c = 3;
console.log(window.a); // 1
console.log(window.b); // undefined
console.log(window.c); // undefined