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 就抓不到了。
forloop 應全面使用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 的windowobject,但let不會- 實務上建議全面使用
let取代var