2024-11-21 情境式說明 vue 的this
2024-11-21 情境式說明 vue 的this
this
確實有點麻煩,因為它的值會根據執行時的情境(上下文)改變。讓我們用一個生活化的情境來類比說明,這樣更容易理解。
情境設定:餐廳服務員的角色變化
假設我們有一位服務員(你可以把他想像成代碼中的 this
),他在不同場合有不同的「職責」(上下文),因為他身處的情境會影響他應該「服務」誰。
情境 1:在餐廳工作
1 | const restaurant = { |
- 服務員的角色(
this
): 他在餐廳,當然知道服務的是餐廳的客人。 - 結果: 他會正確地說出餐廳的名字。
類比:
在這裡,this
指向 restaurant
,因為 service
方法是從 restaurant
物件內被調用的。
情境 2:被外派到婚禮現場
1 | const weddingEvent = restaurant.service; |
- 服務員的角色(
this
): 被派去婚禮現場,但沒有告訴他婚禮現場的名字,他變得迷茫。 - 結果: 他無法正確地說出「歡迎光臨」後的內容。
類比:
this
失去了原本的指向,默認指向全局(瀏覽器中是 window
,Node.js 中是 global
)。window.name
默認是 undefined
,所以輸出結果不完整。
情境 3:在婚禮現場給他備忘錄
1 | const weddingEvent = restaurant.service.bind({ name: "幸福婚禮會場" }); |
- 服務員的角色(
this
): 他被給了一張備忘錄,知道現在要服務的是「幸福婚禮會場」。 - 結果: 他可以正確地說出「歡迎光臨幸福婚禮會場」。
類比:
在這裡,我們使用了 bind
方法,手動把 this
綁定到 { name: "幸福婚禮會場" }
。
情境 4:服務員的記性不好,用了箭頭函式
1 | const restaurant = { |
- 服務員的角色(
this
): 他記不住自己身處的地方,只認為是「上級指派」的。 - 結果: 他不知道當前餐廳的名字。
類比:
箭頭函式中的 this
不會指向當前物件,而是根據外層上下文來決定。這裡的外層上下文是 window
,所以 this.name
是 undefined
。
情境 5:用箭頭函式保證清晰記憶
1 | const restaurant = { |
- 服務員的角色(
this
): 他得到了一個隨身備忘錄(箭頭函式),隨時告訴他「你是在餐廳裡」。 - 結果: 他正確地服務客人。
類比:
箭頭函式不會創建自己的 this
,所以會自動繼承外層函式的上下文(restaurant
),因此能正確使用 this.name
。
Vue 中的情境:碼表應用的 this
問題
讓我們用你的 Vue 碼表作例子:
問題情境:傳統函式導致 this
丟失
1 | methods: { |
- 服務員的角色(
this
): 他去做定時器的工作,但忘了自己屬於 Vue 實例。 - 結果: Vue 實例的
time
無法被訪問,因為this
指向window
。
解決方法:用箭頭函式
1 | methods: { |
- 服務員的角色(
this
): 他隨身帶著備忘錄(箭頭函式),記得自己是 Vue 實例的一部分。 - 結果: 他能正確操作 Vue 實例的數據。
總結:情境帶出的 this
特性
this
的值由執行上下文決定。- 普通函式:
this
由調用方式決定,默認指向全局物件。 - 箭頭函式:
this
繼承自定義它時的外層上下文。
- 普通函式:
在 Vue 中,保持
this
指向 Vue 實例很重要。- 用箭頭函式可以避免上下文丟失。
- 或者用
bind
、that
保存正確的上下文。
生活化類比:
- 「服務員在不同情境下服務不同的對象」形象地描述了
this
的上下文問題。
- 「服務員在不同情境下服務不同的對象」形象地描述了