一次搞懂 JavaScript 的 this
前言
在 FB 直播看到 姚偉揚 老師再說明 javascript 各種 this 的分辨,在此紀錄各種案例。
議程重點
- 一般函式的 this
- ES6 箭頭函式的 this
- Vue 組件的 this
- bind/apply/call 的 this
一般函式的 this
this
主要是 看函式(function)怎麼執行 的,下列為常見的分辨的方法
- 直接執行 → global
- 作為物件的成員函式執行 → 該物件
- 作為 DOM 事件偵聽函式 → 該 DOM
- 作為建構函式 → 建構出來的實例
下列為各種 this 的判斷
範例 1
1 | function a() { |
範例 2
1 | function a() { |
範例 3
1 | const obj = { |
因為 b()
是直接執行,並不是以 obj.b()
方式執行。
範例 4
1 | <button id="btn">btn</button> |
1 | function a() { |
範例 5
1 | <button id="btn">btn</button> |
1 | function a() { |
因為 a()
是直接執行。
1 | function a() { |
範例 6
1 | <button id="btn">btn</button> |
1 | const obj = { |
1 | btn.addEventListener("click", function() { |
範例 7
1 | <button id="btn">btn</button> |
1 | function a() { |
1 | btn.addEventListener("click", function() { |
善用的方式
另外一種思考的方式,我們在寫物件內的函式時,為了確保 this 能夠正確運作會先將它賦予在另一個變數上 (that, self, vm…)。
1 | var auntie = { |
箭頭函式的 this
口訣:箭頭函式裡面的 this 等於 外面的 this
白話文:箭頭函式裡的 this 主要是依據 外層函式(function)裡的 this 是什麼就跟著是什麼。
規則
1 | function x(){ |
範例 1
1 | <button id="btn">btn</button> |
1 | const a = () => { |
範例 2
1 | const obj = { |
範例 3
1 | <button id="btn">btn</button> |
1 | function a() { |
與 一般函式的範例 3 有點類似,雖然 b()
都是直接執行,
不過因為箭頭函式裡的 this 主要是依據 外層函式(function)裡的 this 是什麼就跟著是什麼,
所以 a()
的 this
是 DOM 元素,所以這裡的 b()
的 this
也會跟著是 DOM 元素。
範例 4
Q:包了好幾層的箭頭函數的 this 也是指向 windows 嗎?
A:從 c()
一層撥一層 直到 function a()
,再參照 a()
的 this
是指向誰。
1 | function a() { |
Vue 組件的 this
全部皆指向 vue 實例 本身
範例 1
1 | var vm = new Vue({ |
範例 2
1 | var vm = new Vue({ |
範例 3
若是 vue 的建立是包在 函數
裡面時,使用 箭頭函數
,則 this 要看外層函數的 this。
1 | function init() { |
此時箭頭函式裡的this會指向外層函式的this,
所以在vue要使用this的話,建議使用 一般函式 寫法。
bind/apply/call 的 this
一般函式使用 bind/apply/call 時,
this
就是所傳入的物件箭頭函式使用 bind/apply/call 時,
this
不會有變化,規則一樣是 依據外層函式(function)裡的 this 是什麼就跟著是什麼。
範例 1
1 | <button id="btn">btn</button> |
1 | function add(x, y) { |
範例 2
1 | <button id="btn">btn</button> |
1 | const add = (x, y) => { |