this的迷之指向
var obj = {
foo:function(){console.log(this)
}
}var bar = obj.foo
obj.foo()// 打印出的 this 是 objbar()// 打印出的 this 是 window請(qǐng)解釋最后兩行函數(shù)的值為什么不一樣礁蔗。
//ES5函數(shù)調(diào)用的3種形式
func(p1, p2)
obj.child.method(p1, p2)
func.call(context, p1, p2)
//語(yǔ)法糖
func(p1, p2) 等價(jià)于
func.call(undefined, p1, p2)
obj.child.method(p1, p2) 等價(jià)于
obj.child.method.call(obj.child, p1, p2)
//第三種func.call(context, p1, p2)//this,就是上面代碼中的 context设拟。
functionfunc(){
console.log(this)
}func()//等價(jià)于functionfunc(){
console.log(this)
}func.call(undefined)// 可以簡(jiǎn)寫(xiě)為 func.call()//上面是打印出來(lái)是什么慨仿?
按理說(shuō)打印出來(lái)的 this 應(yīng)該就是 undefined 了吧,但瀏覽器里有一條規(guī)則: 如果你傳的 context 就 null 或者 undefined纳胧,那么 window 對(duì)象就是默認(rèn)的 context(嚴(yán)格模式下默認(rèn) context 是 undefined) 因此上面的打印結(jié)果是 window镰吆。
//如果你希望這里的 this 不是 window,很簡(jiǎn)單:func.call(obj)// 那么里面的 this 就是 obj 對(duì)象了
obj.child.method(p1, p2) 的 this 如何確定varobj = {
foo: function(){
console.log(this)
}
}
obj.foo()
按照「轉(zhuǎn)換代碼」跑慕,我們將 obj.foo() 轉(zhuǎn)換為
obj.foo.call(obj)
好了万皿,this 就是 obj。搞定。
回到題目varobj = {
foo:function(){console.log(this)
}
}varbar = obj.foo
obj.foo()// 轉(zhuǎn)換為 obj.foo.call(obj)相寇,this 就是 objbar()// 轉(zhuǎn)換為 bar.call()// 由于沒(méi)有傳 context// 所以 this 就是 undefined// 最后瀏覽器給你一個(gè)默認(rèn)的 this —— window 對(duì)象