通過(guò)查了很多資料我終于能理明白this到底指向誰(shuí)了,首先我們得從函數(shù)調(diào)用的形式來(lái)說(shuō)
函數(shù)調(diào)用
JS中有三種函數(shù)調(diào)用形式:
func(p1, p2)
obj.child.method(p1, p2)
func.call(context, p1, p2) // 先不講 apply
一般,初學(xué)者都知道前兩種形式,而且認(rèn)為前兩種形式「優(yōu)于」第三種形式。
從看到這篇文章起,你一定要記住,第三種調(diào)用形式,才是正常調(diào)用形式:
func.call(context, p1, p2)
其他兩種都是語(yǔ)法糖,可以等價(jià)的轉(zhuǎn)變?yōu)閏all的形式:
func(p1, p2) 等價(jià)于
func.call(undefined, p1, p2)
obj.child.method(p1, p2) 等價(jià)于
obj.child.method.call(obj.child, p1, p2)
此處劃重點(diǎn)?。?!
(我們稱此代碼為「轉(zhuǎn)換代碼」,方便下文引用)
至此我們的函數(shù)調(diào)用只有一種形式:
func.call(context, p1, p2)
這樣,this 就好解釋了this,
就是上面代碼中的 context。就這么簡(jiǎn)單。
this 是你 call 一個(gè)函數(shù)時(shí)傳的 context,由于你從來(lái)不用 call 形式的函數(shù)調(diào)用,所以你一直不知道。
先看 func(p1, p2) 中的 this 如何確定:
當(dāng)你寫(xiě)下面代碼時(shí)
function func(){
console.log(this)
}
func()
等價(jià)于
function func(){
console.log(this)
}
func.call(undefined) // 可以簡(jiǎn)寫(xiě)為 func.call()
按理說(shuō)打印出來(lái)的 this 應(yīng)該就是 undefined 了吧,但是瀏覽器里有一條規(guī)則:
如果你傳的 context 不是一個(gè)對(duì)象,那么 window 對(duì)象就是默認(rèn)的 context。
因此上面的打印結(jié)果是 window。
如果你希望這里的 this 不是 window,很簡(jiǎn)單:
func.call(obj) // 那么里面的 this 就是 obj 對(duì)象了
再看 obj.child.method(p1, p2) 的 this 如何確定:
var obj = {
foo: function(){
console.log(this)
}
}
obj.foo()
按照「轉(zhuǎn)換代碼」,我們將 obj.foo() 轉(zhuǎn)換為
obj.foo.call(obj)
好了,this 就是 obj。搞定。
---------------------------總結(jié)------------------------------
- this 就是你 call 一個(gè)函數(shù)時(shí),傳入的 context。
- 如果你的函數(shù)調(diào)用形式不是 call 形式,請(qǐng)按照「轉(zhuǎn)換代碼」將其轉(zhuǎn)換為 call 形式。