ES6 入坑 (ECMASCRIPT6/ ES2015)
筆記
-
IE 以外瀏覽器,超過九成以上都已經支援 ES6 寫法,如果要顧及 IE ,只能透過 babel 轉譯。
-
Scope(區塊):let 所宣告的變數只能做用到代碼塊區域(block scope)中。
// scope let, var
{
var a = 123;
let b = 456;
}
console.log(a);
console.log(b);
for (var a = 0; a < 5; a++) {
}
console.log(a);
for (let b = 0; b < 5; b++) {
}
console.log(b);
- Hoisting(提升):JS 使用 var 的時候,會檢查整份 code 是否被宣告過,如果被宣告為 function 會優先使用。
// 一開始只寫 console 的時候, a 是 not defined
console.log(a);
var a = 3;
// 一旦後面寫個同名的 function,就會提升到前面,a 顯示為一個函式,function 優先權較高
function a() {
}
- Hoisting(提升):JS 使用 let 的時候,如果是使用後才宣告,會報錯。
// 如果改成 let ,會報錯,提示需要先宣告再使用
console.log(b);
let b = 3;
function b() {
}
- Dead Zone:在一個 scope 中,如果有用 let 做宣告,那在 let 之前都無法使用。
var a = 'Mike';
{
console.log(a); // Mike
// scope 裡面可以取到外面的值
var a = 123;
console.log(a); // 123
}
let b = 'Mike';
{
console.log(b); // 報錯
let b = 123;
console.log(b);
}
-
使用 let 只要注意
先宣告,後使用
即可,同時避免 scope 內外宣告相同名稱或重複宣告。 -
const(常數):通常只能設定一次,後面修改會報錯。
const name = 'Mike';
name = 'Michelle' // 會報錯
- const 宣告物件,物件本身無法被修改,但物件內部的參數卻可以修改。
const obj = {
name: 'Mike'
}
obj.name = 'Michelle'; // 物件內部的參數卻可以修改
console.log(obj);
obj = { // 物件本身無法被修
name: 'Michelle'
}
- 箭頭函式:大括號內如果只有一行可以省略大括號,箭頭函式預設會 return,所以 return 也省略。
// 傳統寫法一
function abc() {
return 'abc';
}
// 傳統寫法二:避免 Hoisting 的 function 優先問題發生,程式相對穩定
let abc = function () {
return 'abc';
}
// 箭頭函式
let abc = () => {
return 'abc'
};
// 大括號內如果只有一行可以省略
// 箭頭函式預設會 return,所以 return 也省略
let abc = () => 'abc';
console.log(abc());
-
箭頭函式預設會 return » 學習 Functional Programming
-
Callback hell 中的 this 會代表不同對象。
-
this 問題 - 傳統
var self = this;
解法。 -
this 問題 - 箭頭函式解法,箭頭函式沒有自己的 this,會沿用父層的 this。但要小心本範例如果父層也用箭頭函式,this 就會指到 window。
-
字串模板:ES6 的 `(反引號) 可直接將 HTML 原始內容放入,支援換行。參數可以做運算、帶 function。
let btnText = "Button";
// 傳統只有單引號與雙引號可用,有時候還要配合反斜線和加號。
let htmlTemplate1 = '<div><a href="#">' + btnText + '</a></div>';
let htmlTemplate2 = "<div><a href='#'>" + btnText + "</a></div>";
let htmlTemplate3 = "<div><a href=\"#\">" + btnText + "</a></div>";
// ES6 的 `(反引號) 可直接將 HTML 原始內容放入,支援換行。
// 參數可以做運算、帶 function
let getNum = () => {
return Math.floor(Math.random() * 10);
};
let htmlTemplateES6 = `
<div>
<a href="#">${btnText + '!!! ' + getNum()}</a>
</div>
`;
document.body.innerHTML = htmlTemplateES6;
- 函式
預設值
寫法。
// ES5 設定預設值寫法
function test1(a, b, c, d) {
a = a || 'AAA'
b = b || 'BBB'
c = c || 'CCC'
d = d || 'DDD'
console.log(a, b, c, d);
}
console.log(test1());
// ES6 預設值寫法
function test1_ES6(a = 'AAA', b = 'BBB', c = 'CCC', d = 'DDD') {
console.log(a, b, c, d);
}
console.log(test1_ES6());
- 函式預設值寫法 -
物件拆解
。
// ES5 設定預設值寫法
function test2(obj) {
obj = obj || {}
obj.a = obj.a || 'AAA'
obj.b = obj.b || 'BBB'
obj.c = obj.c || 'CCC'
obj.d = obj.d || 'DDD'
console.log(obj);
}
console.log(test2());
// ES6 預設值寫法 - 物件拆解
function test2_ES6({ a = 'AAA', b = 'BBB', c = 'CCC', d = 'DDD' }) {
console.log(a, b, c, d);
}
console.log(test2_ES6({ a: 'Mike' }));
- 陣列拆解
let arr = [1, 2, 3, 4, 5, 6];
// let a = arr[0], b = arr[1], c = arr[2];
let [a, b, ...c] = arr;
// 頭兩個分給 a, b,剩下的都分給 c
console.log(a);
console.log(b);
console.log(c);
- 拆解應用一
let mike = {
name: 'Mike',
bType: 'B',
sex: 'male'
}
let { name, bType, sex } = mike;
// import { name, bType, sex } from 'mike';
// node_modules 常看到這種用法
console.log(name, bType, sex);
- 拆解應用二
let name = 'Mike';
let sex = 'male';
// 傳統寫法:浪費人生,要打兩次?
let mike = {
name: name,
sex: sex
}
console.log(mike);
// ES6 寫法
let mike_ES6 = {
name,
sex
}
console.log(mike_ES6);
-
Promise:用來保證 function 執行的先後順序。
-
未使用 Promise,執行順序不如預期。
-
使用 Promise 做流程控制,把非同步做成同步。
function fn1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(1);
resolve(); // 做完事情要告訴他 resolve
}, 0);
})
}
function fn2() {
console.log(2);
}
fn1().then(fn2) //依序顯示 1, 2
# 同步:依序執行,後者要等前者做完顯示結果後才能開始執行。
A[run] > A[wait] > A[finish] > B[run] > B[wait] > B[finish] > C[run] ...
# 非同步:依序執行,誰先做完就先顯示結果。
A[run] > A[wait] > A[wait] > A[wait] > A[wait] > A[finish]
> B[run] > B[wait] > B[finish]
> C[run] > C[wait] > C[finish]
- async/await: 屬於 ES7 的語法,基於 Promise,Generator 的升級版。同步的視覺,非同步的享受。注意 Nodejs 從 v7.6.0 才開始支援 async/await。
function fn1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(1);
resolve(); // 做完事情要告訴他 resolve
}, 0);
})
}
function fn2() {
console.log(2);
}
async function run() {
await fn1();
fn2();
}
run();
- 使用 async/await 記得加上 try/catch,避免出錯。