JS 函式中的 this
this 是 js 裡函式執行時時自動產生的物件,隨著 function 執行場合的不同,this 所指向的值,也會有所不同。在多數情況下,this會指向呼叫 function 的物件。以下介紹幾種this的指向。
簡單呼叫(Simple call)
當我們直接呼叫函式時,function 裡的 this 指的會是 window。所以當 window 底下有全域變數 father時,this.father 就會取到 小名這個值。
下面我們將 function 中包著 function,但只要是直接呼叫,this 都是屬於全域
callback function 被呼叫也是屬於 simple call,會取到 window 下的 myName;
1 | var myName = '小名'; |
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 | var obj = { |
.call() 與 .apply()
基本上 .call() 或是 .apply() 都是去呼叫執行這個 function ,並將這個 function 的 context 替換成第一個參數帶入的物件。 換句話說,就是強制指定某個物件作為該 function 執行時的 this。
可將 Ming 傳入並取代 this,後面帶上一個參數 2 則是函式的參數。因此
- .call() 前者為套用 this 的物件,後者以後都是函式的參數。
- .apply() 前者一樣套用this的物件,後者以陣列的方式傳入參數。
1 | fn.call(1, '小名', '杰倫') // this => {1} |
當使用 call 傳入的第一個參數不是物件而是純值時,string、number、boolean 會被包裝成物件,undefined、null 則會被替換成 window。
簡易呼叫時盡可能不要調用this,因為它的本質就是 undefined。
1 | // 以下兩行實際上是一樣的。 |
簡易呼叫其實就相當於執行 call 但傳入的值是 undefined,undefined 在一般模式會被替換成 window,而在嚴格模式則會維持 undedined。
.bind()、 .call() 、.apply()的差異
bind() 讓這個 function 在呼叫前先綁定某個物件,使它不管怎麼被呼叫都能有固定的 this。
尤其常用在像是 callback function 這種類型的場景,可以想像成是先綁定好 this,然後讓 function 在需要時才被呼叫的類型。
而 .call() 與 .apply() 則是使用在 context 較常變動的場景,依照呼叫時的需要帶入不同的物件作為該 function 的 this。 在呼叫的當下就立即執行。