[Javascript] ES6 — Arrow Function 箭頭函數

Dosmanthus
6 min readJun 7, 2017

--

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"]

參考:

--

--

No responses yet