首先,我們先來看一下與普通函數相比箭頭函數是什麼樣子:
普通函數:
function foo(x,y){
return x+y;
}
箭頭函數:
var foo = (x,y) => x+y;
通過上面簡單的例子,我們可以看到箭頭函數定義包括
- 一個參數列表,參數列表可以包含零個或多個參數,如果參數的個數不是一個的話要用(..)包圍起來。
- 然後是=>。
- 函數體放在最後。
所以,在前面的箭頭函數中,箭頭函數就是(x,y) => x+y這一部分,然後這個函數引用被賦給變量foo。
只有在函數體的表達式個數大於1個,或者函數體包含非表達式語句的時候才需要用{..}包圍。如果只有一個表達式,並且省略了包圍的{..}的話,則意味着表達式前面省略了return。
關於箭頭函數,我們還應該明白
- 箭頭函數是函數表達式,並不存在箭頭函數聲明。
- 箭頭函數不只是更短的語法,而是this。接下來我們來了解一下箭頭函數的this。
箭頭函數this的指向與普通函數的this指向是完全不同的(關於普通函數的this,可以參考我的這篇文章https://blog.csdn.net/weixin_38858002/article/details/79372894)。在箭頭函數中是不存在函數本身的this的,所以導致箭頭函數內部的this就是外層this,同時也就導致箭頭函數不能用做構造函數。
關於this的具體用法我們通過下面的一個例子來了解一下:
var obj = {
foo: function(){
var that = this;
btn.addEventListener('click',function(){
that.foo(..)
},true);
}
}
當我我們點擊一個按鈕想要觸發一個函數時,如果使用普通函數,我們就需要先將this保存起來。因爲如果不提前保存起來,this就會指向調用它的這個對象,也就是這個按鈕。但是如果我們使用箭頭函數的話就不用這麼麻煩了。
var obj = {
foo: function(){
btn.addEventListener('click',()=>{
this.foo(...);
},true);
}
}
但並不是說所有的情況下我們都可以這樣做的,比如下面這個例子:
var obj = {
foo: ()=>{
this.bar(..);
},
bar: ()=>{
...
}
}
obj.foo();
儘管我們以obj.foo()的形式調用,但是this的引用還是會失敗。因爲在這段代碼中,this.bar(..)中的this是外層函數的this,在這裏也就是全局對象的this,這與我們想要達到的效果是相背的。
除了this,箭頭函數也沒有自己的argument,同樣是繼承外層的。
最後來總結一下使用箭頭函數的情況:
- 如果你有一個簡短額函數表達式,其中唯一的語句就是return某個值,且這個函數內部沒有this引用,且沒有自身引用,且不會要求函數執行這些,那麼久安全的把它重構爲箭頭函數。
- 如果你有一個內層函數表達式,依賴於在包含它的函數中調用var that = this或.bind(this)來確保適當的this綁定,那麼這個內層函數表達式就可以安全的轉爲箭頭函數。
- 如果你的內層函數表達式依賴於封裝函數中某種像 var args =
Array.prototype.slice.call(arguments)來保證arguments,那麼這個內層函數就可以安全的轉爲箭頭函數。