普通函數中this
的綁定是很複雜多變的,ES6箭頭函數=>
以特定的方式改變this
的行爲特性,解決this
相關編碼的
一個特殊又常見的痛點。javascript
箭頭函數也不老是比普通函數好,當這個函數越長,=>
帶來的好處越小,這個函數越短,=>
帶來的好處越大。因此
只在確實須要簡短的在線函數表達式的時候才用=>
,而對於那些通常長度的函數則無需改變。java
var controller = { makeRequest: function(){ var self = this; btn.addEventListener( "click", function(){ // .. self.makeRequest(); }, false ); } };
在這個例子中,咱們使用var self = this
這一Hack,而後使用self.makeRequest
,由於咱們傳入addEVentListener
的回調函數內部,this
綁定和makeRequest()
自己的this
綁定不同。普通函數中的this綁定是動態的,咱們須要經過self
變量依賴詞法做用域的可預測性。數組
箭頭函數中的this
綁定不是動態的,而是詞法的。babel
var controller = { makeRequest: function(){ btn.addEventListener( "click", () => { // .. this.makeRequest(); }, false ); } };
咱們使用=>
箭頭函數替代普通函數,箭頭函數回調中的詞法this
和makeRequest()
中是同樣的。=>
就是var self = this
的詞法替代形式。函數
咱們使用Babel
轉換一下:this
發現,在使用=>
以前,也就是箭頭函數的外層,先使用var self = this
保存了this
編碼
再看一個例子:spa
var controller = { makeRequest: () => { // .. this.helper(); }, helper: () => { // .. } }; controller.makeRequest();
儘管咱們以 controller.makeRequest(..) 的形式調用,this.helper 引用仍是會失敗,由於
這裏的 this 並不像日常同樣指向 controller。那麼它指向哪裏呢?它是從包圍的做用域中
詞法繼承而來的 this。在前面的代碼中也就是全局做用域,其中 this 指向那個全局對象。code
this
,只有詞法this
,繼承自父層arguments
數組,只有詞法arguments
,繼承自父層super
new.target
做用域和做用域鏈對象
必定要記住箭頭函數的特色,在適當的地方使用。
若是是寫對象的方法,要使用普通函數,由於普通函數中有this
,通常狀況下指向該對象,而箭頭函數沒有this,則訪問不到對象的其餘屬性了。
若是返回值是一個簡單的表達式,且這個函數內部沒有this
的引用,且沒有自身引用(遞歸、綁定/解綁定,且不會要求函數執行這些,可使用箭頭函數。
若是函數內部有不少語句,仍是要用普通函數,保證可讀性。