ECMAScript 2015 是 ECMAScript 歷史上最重要一次升級,也讓 ECMAScript 終於趕上主流程式語言高度,若要明顯的分辨 ES5 與 ES6,最明顯的方式的方式就是看有沒有使用 let
。
Verson
ECMAScript 2015
Let
宣告變數於 block {}
內。
var
宣告變數於 function 內或 function 外 (global)
Scope
function f() {
var x = 1
if (true) {
var x = 2
console.log(x)
}
console.log(x)
}
f()
ES5 與 ES6 都可執行,但結果卻是兩個 2
。
var
因為 hoisting 在 creation phase 就已經定義 x
,且 scope 為 function 內,因此離開 if (true)
仍然為 2
。
function f() {
let x = 1
if (true) {
let x = 2
console.log(x)
}
console.log(x)
}
f()
改用 ES6 的 let
,結果為 2
與 1
。
第 4 行
if (true) {
let x = 2;
console.log(x);
}
使用 let
後,其 scope 為 {}
而非 function,只有在 {}
為 2
,離開 {}
就變回 1
。
以主流程式語言而言,變數的 scope 都是 block
{}
而非 function,因此 ECMAScript 的let
較符合大家習慣,因此 TC39 建議全面使用let
取代var
function f(cnt) {
for (var i = 0; i < cnt; i++) {}
console.log(i)
}
f(5)
var
為 function level,因此 for
loop 執行完還存在。
function f(cnt) {
for (let i = 0; i < cnt; i++) {}
console.log(i)
}
fn(5)
let
為 block level,超出 for
loop 就抓不到了。
for
loop 應全面使用let
避免 side effect
var x = 'global'
let y = 'global'
console.log(window.x)
console.log(window.y)
var
與 let
雖然都可建立 global 變數,但 var
會污染 DOM 的 window
object,但 let
不會。
若要使用 global 變數,應全面使用
let
取代var
Redeclaration
var x = 2
console.log(x)
var x = 3
console.log(x)
ES5 與 ES6 都可以執行。
var
允許對 variable 重複宣告。
let x = 2;
console.log(x);
let x = 3;
console.log(x);
// SyntaxError
ES5 與 ES6 都無法執行。
let
不允許對 variable 重複宣告。
function fn(x) {
switch(x) {
case 0:
var y = 2;
console.log(y);
break;
case 1:
var y = 3;
console.log(y);
break;
}
}
fn(1);
// 3
ES5 與 ES6 都可執行。
因為 var
會 hoisting,所以允許 redeclaration。
function fn(x) {
switch(x) {
case 0:
let y = 2;
console.log(y);
break;
case 1:
let y = 3;
console.log(y);
break;
}
}
fn(1);
若將 var
改成 let
,則 ES5 與 ES6 都無法執行。
因為 let 認 {}
為 scope,不允許 redeclaration。
function f(x) {
switch(x) {
case 0: {
let y = 2
console.log(y)
break
}
case 1: {
let y = 3
console.log(y)
break
}
}
}
f(1)
在每個 case
加上 {}
,則可以 redeclaration。
Conclusion
var
為 function level 或 global level;而let
為 block levelvar
的 global 變數會污染 DOM 的window
object,但let
不會- 實務上建議全面使用
let
取代var