[Javascript] ES6 — Arrow Function 箭頭函數
Javascript 在 ES6 中加入了 lambda表達式 Arrow function,Lambda 表達式是一種簡易的函數定義形式,通常在編程語言用來簡化代碼的結構。Arrow function比起一般的函數擁有更短的語法,所有箭頭函數都是匿名函數。 函數體不止一行時,應該用花括號,並顯式地返回( Explicit return)。
// 沒有參數時
() => {...}
// 一個參數時可以省略()
name => {
return `Hello ${name}!`
}
// 隱式返回值(implicit return)。
name => `Hello ${name}!`
當使用隱式返回時,Object Literal 必須用括號括起來。
const race = '100m Dash'
const winners = ['David', 'Tony', 'Pierce']const win = winners.map((winner, i) => ({name: winner, race, place: i + 1}));
其他範例:
const ages = [19, 53, 41, 26, 19, 33, 62];
const old = ages.filter(age => age >= 50);
this 變數綁定
原本Javascript的函式設計,是在被呼叫時以呼叫它的物件作為預設this值,或是在全域呼叫時以window或全域物件作為預設this(或是嚴格模式下是undefined)。
這種設計在物件之成員函式內有函式時,特別需要注意:
var person = {
first: "Doug",
actions: ['bike', 'hike', 'ski', 'surf'],
printActions() {
this.actions.forEach(function(action) {
var string = this.first + " likes to " + action;
console.log(string)
});
}
};person.printActions();
// undefined likes to bike
// undefined likes to hike
// undefined likes to ski
// undefined likes to surf
因為person.printActions()
調用時,前面物件為 person object,故 printActions()
內的this指向person。但因為 forEach
內調用的函數前方並未有物件,故函數內的this指向全域物件,所以輸出會是全域變數的first
的值,返回 undifined
。
反之,箭頭函數的this是Lexical this
(詞彙上的 this 變數),是從詞彙週邊的作用域中捕捉this值,作為自己的預設this值,也就是在定義時繼承了 parent 的 this。
var person = {
first: "Doug",
actions: ['bike', 'hike', 'ski', 'surf'],
printActions() {
this.actions.forEach(action => {
var string = this.first + " likes to " + action;
console.log(string)
});
}
};// Doug likes to bike
// Doug likes to hike
// Doug likes to ski
// Doug likes to surf
下面情況不要使用箭頭函數
- 當你需要綁定函數到物件上
var calculate = {
array: [1, 2, 3],
sum: () => {
console.log(this === window); // => true
return this.array.reduce((result, item) => result + item);
}
};
console.log(this === window); // => true
// Throws "TypeError: Cannot read property 'reduce' of undefined"
calculate.sum();
當調用 calculate.sum()
方法時, this還是綁定在 window
object 上,this.array
其實是 window.array
(undefined)。
- 當你需要新增一個 prototype method 時
情況和前一個類似:
function MyCat(name) {
this.catName = name;
}
MyCat.prototype.sayCatName = () => {
console.log(this === window); // => true
return this.catName;
};
var cat = new MyCat('Mew');
cat.sayCatName(); // => undefined
- 當你需要 arguments object 時
const orderChildren = () => {
const children = Array.from(arguments);
return children.map((child, i) => {
return `${child} was child #${i + 1}`;
});
}> orderChildren('toby', 'danny', 'patty')
<- Uncaught ReferenceError: arguments is not defined
改用 function 定義函數:
const orderChildren = function() {
const children = Array.from(arguments);
return children.map((child, i) => {
return `${child} was child #${i + 1}`;
});
}> orderChildren('toby', 'danny', 'patty')
<- ["toby was child #1", "danny was child #2", "patty was child #3"]
參考: