ES6标準新增了一種新的函數:Arrow Function(箭頭函數)。為什麼叫Arrow Function?因為它的定義用的就是一個箭頭:
x => x * x
相當于:
function(x){
return x*x;
}
箭頭函數相當于匿名函數,并且簡化了函數定義。
箭頭函數表達式的文法比函數表達式更簡潔,并且沒有自己的this,arguments,super或new.target。箭頭函數表達式更适用于那些本來需要匿名函數的地方,并且它不能用作構造函數。
箭頭函數有兩種格式,一種像上面的,隻包含一個表達式,連{ … }和return都省略掉了。還有一種可以包含多條語句,這時候就不能省略{ … }和return:
x => {
if (x > 0) {
return x * x;
}
else {
return - x * x;
}
}
如果參數不是一個,就需要用括号()括起來:
// 兩個參數:
(x, y) => x * x + y * y
// 無參數:
() => 3.14
// 可變參數:
(x, y, ...rest) => {
var i, sum = x + y;
for (i=0; i<rest.length; i++) {
sum += rest[i];
}
return sum;
}
如果要傳回一個對象,就要注意,如果是單表達式,這麼寫的話會報錯:
// SyntaxError:
x => { foo: x }
因為和函數體的{ … }有文法沖突,是以要改為:
// ok:
x => ({ foo: x })
this
箭頭函數看上去是匿名函數的一種簡寫,但實際上,箭頭函數和匿名函數有個明顯的差別:箭頭函數内部的this是詞法作用域,由上下文确定。
回顧前面的例子,由于JavaScript函數對this綁定的錯誤處理,下面的例子無法得到預期結果:
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = function () {
return new Date().getFullYear() - this.birth; // this指向window或undefined
};
return fn();
}
};
現在,箭頭函數完全修複了this的指向,this總是指向詞法作用域,也就是外層調用者obj:
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = () => new Date().getFullYear() - this.birth; // this指向obj對象
return fn();
}
};
obj.getAge(); // 25
更多箭頭函數示例如下:
// 空的箭頭函數傳回 undefined
let empty = () => {};
(() => 'foobar')();
// Returns "foobar"
// (這是一個立即執行函數表達式,可參閱 'IIFE'術語表)
var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10
let max = (a, b) => a > b ? a : b;
// Easy array filtering, mapping, ...
var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b);
// 66
var even = arr.filter(v => v % 2 == 0);
// [6, 0, 18]
var double = arr.map(v => v * 2);
// [10, 12, 26, 0, 2, 36, 46]
// 更簡明的promise鍊
promise.then(a => {
// ...
}).then(b => {
// ...
});
// 無參數箭頭函數在視覺上容易分析
setTimeout( () => {
console.log('I happen sooner');
setTimeout( () => {
// deeper code
console.log('I happen later');
}, 1);
}, 1);
var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10
let max = (a, b) => a > b ? a : b;