一次搞懂 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) => { |
