本篇用來整理自己所理解的 JavaScript 中的 this
This 是誰
this 的指向主要與怎麼呼叫有關,最簡單的辨識方式就是,
執行函式時前方不帶物件的話就會指向 window 也就是全域,
如果前方有物件的話就會指向前方的物件,但要注意,不管有幾個物件,只會往前找一個,
重點不在怎麼定義的,而是執行的當下前方有沒有物件。
呼叫的方式的差異
1. 直接呼叫
1 | var name = '全域'; |
使用直接呼叫的話 this 會指向全域,因為執行函式時前方並沒有任何的物件。
2. 呼叫物件中的函式
1 | var name = '全域'; |
本例中呼叫函式的方式為area.callThis()
,所以只要找前方的物件就可以知道 this 是誰,
本例中的 this 就是位於物件 area 內的 name,也就是區域。
3. 立即函式
1 | var name = '全域'; |
使用立即函式的話,因為前方沒有物件,因此也會指向全域。
4. 物件裡的物件
1 | var name = '全域'; |
一樣的原則,this 會根據呼叫的方式而改變,area.callThis()
會讓 this 指向物件 area,所以是第一層,
而area.secArea.callThis()
會讓 this 指向 secArea,所以是第二層,
記得一開始說過嗎不管有幾個物件,只會往前找一個。
5. 重新定義
1 | var name = '全域'; |
將函式重新定義一個變數,並直接呼叫變數,
這時候因為前方沒有物件,所以這裡的 this 一樣會指向全域。
閉包
這篇不說明閉包的概念,僅說明閉包對 this 的影響。
至於閉包對 this 有什麼影響呢?
閉包不會影響 this 的指向,一樣是根據呼叫時前方有沒有物件來決定。
call、apply、bind
call
1 | function callThis() { |
call 可以直接指定 this 的指向,第一個帶入的參數就是 this 的指向。
而為什麼帶入undefined
會指向 window 呢?
因為在非嚴苛模式時, null、undefined 將會被置換成全域變數。
參考
apply
與 call 類似,差別在傳入的參數用陣列表示。
bind
1 | var hello = callName.bind(this 的指向); |
也是與 call、apply 類似,不過寫法不太一樣,如上。
箭頭函式
箭頭函式沒有 this,他會去找外層作用域的 this,
因此可以透過先定義 this 來避免找不到 this。