基本用法
ES6允許用“箭頭” (=>)定義函數(shù)
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
如果箭頭函數(shù)不需要參數(shù)或需要多個參數(shù)锌俱,就使用一個圓括號代表參數(shù)部分鸽嫂。
var f = () => 5;
// 等同于
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
// 如果箭頭函數(shù)的代碼塊部分多于一條語句,就要使用大括號將它們括起來卤材,
并且使用return語句返回洲胖。
由于大括號被解釋為代碼塊,所以如果箭頭函數(shù)直接返回一個對象鹊杖,必須在對象外面加上括號悴灵,否則會報(bào)錯。
// 報(bào)錯
let getTempItem = id => { id: id, name: "Temp" };
// 不報(bào)錯
let getTempItem = id => ({ id: id, name: "Temp" });
使用注意點(diǎn)
箭頭函數(shù)有幾個使用注意點(diǎn)骂蓖。
(1)函數(shù)體內(nèi)的this對象积瞒,就是定義時所在的對象,而不是使用時所在的對象登下。
(2)不可以當(dāng)作構(gòu)造函數(shù)茫孔,也就是說,不可以使用new命令庐船,否則會拋出一個錯誤银酬。
(3)不可以使用arguments對象,該對象在函數(shù)體內(nèi)不存在筐钟。如果要用揩瞪,可以用 rest 參數(shù)代替。
(4)不可以使用yield命令篓冲,因此箭頭函數(shù)不能用作 Generator 函數(shù)李破。
上面四點(diǎn)中,第一點(diǎn)尤其值得注意壹将。this對象的指向是可變的嗤攻,但是在箭頭函數(shù)中,它是固定的诽俯。
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
var id = 21;
foo.call({ id: 42 });
// id: 42
上面代碼中妇菱,setTimeout的參數(shù)是一個箭頭函數(shù),這個箭頭函數(shù)的定義生效是在foo函數(shù)生成時暴区,而它的真正執(zhí)行要等到 100 毫秒后闯团。如果是普通函數(shù),執(zhí)行時this應(yīng)該指向全局對象window仙粱,這時應(yīng)該輸出21房交。但是,箭頭函數(shù)導(dǎo)致this總是指向函數(shù)定義生效時所在的對象(本例是{id: 42})伐割,所以輸出的是42.
箭頭函數(shù)可以讓setTimeout里面的this候味,綁定定義時所在的作用域刃唤,而不是指向運(yùn)行時所在的作用域。下面是另一個例子白群。
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭頭函數(shù)
setInterval(() => this.s1++, 1000);
// 普通函數(shù)
setInterval(function () {
this.s2++;
}, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0
上面代碼中尚胞,Timer函數(shù)內(nèi)部設(shè)置了兩個定時器,分別使用了箭頭函數(shù)和普通函數(shù)川抡。前者的this綁定定義時所在的作用域(即Timer函數(shù))辐真,后者的this指向運(yùn)行時所在的作用域(即全局對象)。所以崖堤,3100 毫秒之后侍咱,timer.s1被更新了 3 次,而timer.s2一次都沒更新密幔。
this指向的固定化楔脯,并不是因?yàn)榧^函數(shù)內(nèi)部有綁定this的機(jī)制,實(shí)際原因是箭頭函數(shù)根本沒有自己的this胯甩,導(dǎo)致內(nèi)部的this就是外層代碼塊的this昧廷。正是因?yàn)樗鼪]有this,所以也就不能用作構(gòu)造函數(shù)偎箫。