[JS] 箭頭函式 Arrow Functions 和 this
前言
箭頭函式(Arrow Functions)是一個ES6的新語法,對我來說前前後後接觸js,一直有碰到this,但要詳細解釋還是很難,因此想藉由這篇讓我更加深this的觀念,會整理出this在箭頭函式的差別與其他this的觀念。另外感謝Kuro大的文章,讓我更容易了解this,分享連結在下面。
箭頭函式(Arrow Functions)
箭頭函式(Arrow Functions)是一個ES6的新語法,與傳統function類似,有點像是傳統function更簡短寫法,但沒有 arguments 參數,this上也有差別。
1 | //傳統函式 |
關於this
傳統函式 this不等於function
this是傳統函式function執行時,自動生成的一個內部物件。隨著執行呼叫場合的不同,所指向的值也會不同。
> 預設綁定(Default Binding) this 指向全域物件
當沒有特定指明 this 的情況下,預設綁定 (Default Binding) this 為 「全域物件」,也就是 window。
- 直接執行呼叫函式 Simple Call
無論把function宣告在哪邊,只要是一般的Simple Call,this指向為 全域物件window。 - 立即函式(IIFE)理論上也是直接呼叫,this也是指向全域
- 非同步的事件 (setTimeout, Ajax等)中callback function 的this也是指向全域。
> 隱含的綁定(Implicit Binding) 透過物件執行呼叫函式
透過物件執行函式時,this指向為該物件。
1 | var obj = { |
- 若宣告嚴格模式的話(use strict),會禁止 this 自動指定為全域物件,this則會變成 undefined。
1 | var obj = { |
- 透過DOM物件來呼叫function時,this也是同樣指向該DOM物件
(event.currentTarget)
重新指向 this
vm, that, self
非同步的事件 (setTimeout, Ajax等)中 callback function 的this指向全域window,因此若我們需要把this指回DOM物件,一般常見的作法是用一個變數(vm, that, self)來代替要指回的this
> 明確綁定(Explicit Binding) bind(),call(),apply()
bind()
在function後面加上 .bind(this) 就可以強制將 () 內的物件帶入至 callback function 內
1 | let familyBaker = { |
call()
apply()
在function後面加上 .call() 或 .apply()來呼叫function,指定第一個帶入的參數作為該function執行呼叫時的this,兩者的差別只在於參數寫法,第一個都是指定this,.call()的第2.3.4…個參數用逗號隔開。.apply()第二個參數為陣列,陣列則可以帶入好幾個參數。
1 | function add(a, b) { |
1 | var animals = [ |
> new 綁定 - 建構式的調用 (As a constructor)
當一個 function 前面帶有 new 被呼叫時,會發生:
- 會產生一個新的物件 (物件被建構出來)
- 這個新建構的物件會被設為該function this的綁定目標,也就是 this 會指向新的物件。
- 除非這個 function 指定回傳 (return) 了他自己的替代物件,否則這個透過 new 產生的物件會被自動回傳。
1 | var mom = '媽咪' |
箭頭函式 this
回到上面說的箭頭函式,this會依據語彙環境的父層區域(parent scope)來綁定。簡單的說法是,箭頭函式沒有this,this指向往上一層找,一般若上層為預設綁定(Default Binding),則指向全域window。
舉例 四種找媽函式 呼叫方式皆為family物件中呼叫 family.findMom1();
1 | var findMom1 = function () { |
DOM物件的例子:
同理在Vue中,使用Ajax回呼用箭頭函式指向為上一層parent scope,便可以使用this呼叫到data
參考資料
[JS] 箭頭函式 Arrow Functions 和 this