JS 函式中的 this

this 是 js 裡函式執行時時自動產生的物件,隨著 function 執行場合的不同,this 所指向的值,也會有所不同。在多數情況下,this會指向呼叫 function 的物件。以下介紹幾種this的指向。

簡單呼叫(Simple call)

當我們直接呼叫函式時,function 裡的 this 指的會是 window。所以當 window 底下有全域變數 father時,this.father 就會取到 小名這個值。

下面我們將 function 中包著 function,但只要是直接呼叫,this 都是屬於全域

Dom 事件中的 this

DOM 搭配 addEventListener 時,此 this 所指向的則是該 DOM。

在上面監聽事件中,呼叫 function 的對象是 alex ,這邊 this 指的就是 alex。

Object 中的 this

如果 function 是在物件下調用,那麼 this 則會指向此物件,無論 function 是在哪裡宣告。

但如果將物件內的函式賦予在一個純粹的變數上並調用它時,這個 this 將會指向全域。

強制指定 this 的方式

如果想強制綁定 this的指向,有以下方法: call() 、 apply() 以及 bind()。

.bind()

1
fun.bind(thisArg[, arg1[, arg2[, ...]]])

在函式後加上 .bind(),第一個參數為指定的 this對象,剩下的參數則為此函式的參數。

1
2
3
4
5
6
7
8
9
10
var obj = {
x: 123
};

var func = function () {
console.log(this.x);
};

func(); // undefined
func.bind(obj)(); // 123

.call() 與 .apply()

基本上 .call() 或是 .apply() 都是去呼叫執行這個 function ,並將這個 function 的 context 替換成第一個參數帶入的物件。 換句話說,就是強制指定某個物件作為該 function 執行時的 this。

可將 Ming 傳入並取代 this,後面帶上一個參數 2 則是函式的參數。因此

  • .call() 前者為套用 this 的物件,後者以後都是函式的參數。

  • .apply() 前者一樣套用this的物件,後者以陣列的方式傳入參數。

.bind()、 .call() 、.apply()的差異

bind() 讓這個 function 在呼叫前先綁定某個物件,使它不管怎麼被呼叫都能有固定的 this。

尤其常用在像是 callback function 這種類型的場景,可以想像成是先綁定好 this,然後讓 function 在需要時才被呼叫的類型。

而 .call() 與 .apply() 則是使用在 context 較常變動的場景,依照呼叫時的需要帶入不同的物件作為該 function 的 this。 在呼叫的當下就立即執行。