本文歸類:面試造火箭,實際擰螺絲恋博。js有三座大山齐佳,this、原型鏈债沮、回調(diào)炼吴,為了幫助小伙伴們翻過大山,取得面試門檻??疫衩,我經(jīng)過整理寫了如下文章硅蹦。
js this指向問題一鏡到底:
為了方便理解,請用大白話理解這幾個詞:
this指向誰:即this是什么,console.log打印出來的this
上下文:那一行代碼的上下內(nèi)容童芹,即該調(diào)用對象的內(nèi)容涮瞻,換句話就是對象本身
1、誰調(diào)用方法假褪,方法內(nèi)的this就指向誰的上下文
請認真看下面第一個簡單的例子:
function foo(){
console.log(this)
}
foo() //window
//相當于
window.foo() //window
//相當于
window.foo.call() //window
函數(shù)調(diào)用的方法等價foo() 等價于 foo.call(context,參數(shù)1,參數(shù)2,...)
我們可以看到上面這幾種寫法this指向都是相同的署咽,因為調(diào)用foo時候其實是window在調(diào)用,我們通常簡寫foo()生音,那么foo.call()寫法你沒見過因為你經(jīng)常簡寫宁否,所以沒這樣寫過,所以你不知道缀遍。那么請你記住慕匠,從下面開始都要在你腦子里形成call調(diào)用的寫法。
請記子虼肌:當call第一個參數(shù)為空時候台谊,會默認為window
let a = 1
let obj = {
a:0,
foo:function(){
console.log(this)
}
}
//1、簡寫
obj.foo() // {a: 0, foo: ?}
//2歹苦、非簡寫默認下青伤,call會傳遞obj做為上下文督怜,因為obj調(diào)用了foo
obj.foo.call(obj) // {a: 0, foo: ?}
//3殴瘦、如果參數(shù)為空,則上下文為window
obj.foo.call() //window
好了号杠,至此你可以用這種方式理解this是什么蚪腋、指向誰了。
2姨蟋、this被call屉凯、apply、bind改變情況眼溶。
我們知道call悠砚、apply、bind可以改變this的指向堂飞,那么我們看到上面的第3種情況
obj.foo.call() //window
我們寫call此時參數(shù)為空灌旧,this指向了window,重復那句話 當call第一個參數(shù)為空時候绰筛,會默認為window
枢泰,所以此時這種情況正常。好铝噩,現(xiàn)在我們試著給他傳遞一個任意參數(shù):
let a = 1
let obj = {
a:0,
foo:function(){
console.log(this) //6666
}
}
obj.foo.call(6666)
`//this指向了我們隨便寫的參數(shù)6666衡蚂,打印結(jié)果得到666666
我們發(fā)現(xiàn)此時this指向了傳遞的6666,所以此時this指向被我們所寫的call改變了,這就是this指向被綁定改變的說法了毛甲。
call年叮、apply兩著類似,區(qū)別只是后面?zhèn)鲄⒏袷讲灰粯?
apply參數(shù)為apply(context,[參數(shù)1玻募,參數(shù)2谋右,參數(shù)3...])
call參數(shù)為call(context,參數(shù)1,參數(shù)2补箍,參數(shù)3...)
好改执,到這里如果沒多大問題的話,你已經(jīng)知道了call坑雅、apply的運用以及區(qū)別辈挂,接下來我們看下bind。
let a = 1
let obj = {
a:0,
foo:function(aa,bb){
console.log(this)
console.log('bb',bb)
}
}
obj.foo.bind(obj,1,2,3,4) //傳參與call相同
沒錯這就是bind與call终蒂、apply兩者的區(qū)別,它不會直接運行這個函數(shù)遥诉,而是返回該this被改變的函數(shù)拇泣,所以請記住:下次你運行這個函數(shù)時候矮锈,里面的this就是你bind過的this霉翔。
至此call、apply苞笨、bind這幾個你就都會了债朵。
3、箭頭函數(shù)this指向
箭頭函數(shù)比較特殊瀑凝,但也沒什么好說的序芦,我們可以發(fā)現(xiàn),上面的普通函數(shù)this不是固定的粤咪,取決于誰調(diào)用它谚中,它才指向誰。那么請反過來記琢戎Α:箭頭函數(shù)this是固定的宪塔,它在被定義時候就已經(jīng)被決定了this的指向。就是說寫了一個箭頭函數(shù)脉顿,那么你的this就相當于已經(jīng)同時被定義死了蝌麸,指向當前環(huán)境父級的上下文。call艾疟、bind来吩、apply無法改變箭頭函數(shù)的this指向敢辩。
至此this指向問題你應該都會了,以后這座山在你心里磨平了弟疆。