整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ
JavaScript 核心觀念(40)-函式以及 This 的運作-最常見的 this:物件的方法調用
前言
接下來就會開始講一推讓許多 JavaScript 開發者煩惱的東西,也就是 this。
最常見的 this:物件的方法調用
首先 this 基本上在 JavaScript 非常的常見,而且是不需要使用這設置就會存在的東西,這是什麼意思呢?
這邊先打開瀏覽器的控制台,並按下 source 中的暫停按鈕,接下來輸入以下程式碼
1 | |
就會看到以下畫面

然後按下 「Step info next function call」就會進入該函式的執行堆疊,這時候就會看到 Scope 裡面會有一個 this

因此 this 只要在執行環境成立時,就會自動生成,因此並不需要我們特別去設定,除此之外在此我們也可以看到目前 this 是指向到 window,因此若此時我們有一個 Global 變數,那麼我們就可以直接使用 this 取得
1 | |

這邊再強調一次 this 並不需要我們特別去設定或是宣告,它本身在存活在每一個執行環境下,其中包含函式的執行環境以及全域執行環境,因此基本上 this 也有一些基本觀念要注意

第一個是我們剛剛一直在強調的,每一個執行環境都有屬於自己的關鍵字 this,第二個觀念若能熟悉的話,基本上大多 this 的指向都可以了解,最後一個則是嚴格模式。
而這邊課程也有列出常見的 this 調用方式

那麼這邊回歸 this 有什麼用呢?
基本上 this 它的指向與我們怎麼定義它並沒有太大的什麼關係,因此它是可以略過函式的定義方式來呼叫並取的特定的物件屬性

而在此 this 在物件的方法中調用是非常的常見

因此我們舉例一段程式碼
1 | |
在此我們可以看到 callName 是基於 data 這個物件底下呼叫的,因此 this 就會指向到 data,所以 console.log(this.name) 就會出現 Ray。
除此之外範例程式碼改成以下,結果也會是相同的
1 | |
因此我們就可以得知,只要它在哪一個物件下呼叫那麼它就會指向到哪一個物件。
接下來這一段在額外調整一個範例程式碼
1 | |
基本上 this 的重點觀念在於是在哪一個物件下呼叫的,那麼它會指向哪一個屬性,所以 data.callName(); 是基於在 data 底下呼叫 callName,因此就會是出現 Ray,這邊前面觀念是完全一樣,而第二個 data.ming.callName(); 的 callName 是基於在 ming 呼叫,因此 callName 就會指向到 ming 而出現 Ray2。
接下來再來額外看一些不同的範例
1 | |
在此我們會發現 callName 出來的結果會是 undefined。
為什麼呢?剛剛有講到 this 的指向最主要與它怎麼呼叫有關係,因此我們將 data.callName 直接賦予到變數 a 中(注意這邊並沒有執行 callName),因此 a 變數在呼叫時,是在 window 下呼叫,而此時的 window 並沒有 myName 這個屬性,因此就會是一個 undefined。
這時候若調整成這樣就可以看到囉~
1 | |
透過該章節我們可以了解到,不管你怎麼定義函式 this 的指向終究只會與它的呼叫有關係而與它的定義方式沒有太大關聯。
最後再寫一個範例
1 | |
上面這一段程式碼,基本上在你輸入之後過一秒會發現 this 竟然會是出現 JavaScript 而不是 Ray,而這邊最主要原因是出在與 this 的簡易呼叫有關係而導致 this 指向跑掉。
參考文獻
整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ