箭頭函數(常用)
ES6 允許使用箭頭(=>)定義函數
箭頭函數對於使用function關鍵字創建的函數有以下區別
-
箭頭函數沒有arguments(建議使用更好的語法,剩餘運算符替代)
-
箭頭函數沒有prototype屬性,沒有constructor,即不能用作與構造函數(不能用new關鍵字調用)
-
箭頭函數沒有自己this,它的this是詞法的,引用的是上下文的this,即在你寫這行代碼的時候就箭頭函數的this就已經和外層執行上下文的this綁定了(這裏個人認爲並不代表完全是靜態的,因爲外層的上下文仍是動態的可以使用call,apply,bind修改,這裏只是說明了箭頭函數的this始終等於它上層上下文中的this)
因爲setTimeout會將一個匿名的回調函數推入異步隊列,而回調函數是具有全局性的,即在非嚴格模式下this會指向window,就會存在丟失變量a的問題,而如果使用箭頭函數,在書寫的時候就已經確定它的this等於它的上下文(這裏是makeRequest的函數執行上下文,相當於講箭頭函數中的this綁定了makeRequest函數執行上下文中的this),所以this就指向了makeRequest中的a變量
箭頭函數中的this即使使用call,apply,bind也無法改變指向(這裏也驗證了爲什麼ECMAScript規定不能使用箭頭函數作爲構造函數,因爲它的this已經確定好了無法改變)
建議
箭頭函數替代了以前需要顯式的聲明一個變量保存this的操作,使得代碼更加的簡潔
ES5寫法不推薦:
ES6箭頭函數:
值得注意的是makeRequest後面的function不能使用箭頭函數,因爲這樣它就會再使用上層的this,而再上層是全局的執行上下文,它的this的值會指向window
setTimeout第一個參數使用了箭頭函數,它會引用上下文的this,而它的外層也是一個箭頭函數,又會引用再上層的this,最上層就是整個全局上下文,即this的值爲window對象,所以沒有變量a
在數組的迭代中使用箭頭函數更加簡潔,並且省略了return關鍵字
不要在可能改變this指向的函數中使用箭頭函數,類似Vue中的methods,computed中的方法,生命週期函數,Vue將這些函數的this綁定了當前組件的vm實例,如果使用箭頭函數會強行改變this,因爲箭頭函數優先級最高(無法再使用call,apply,bind改變指向)
在把箭頭函數作爲日常開發的語法之前,個人建議是去了解一下箭頭函數的是如何綁定this的,而不只是當做省略function這幾個單詞拼寫,畢竟那纔是ECMAScript真正希望解決的問題