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 reference1
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