眾所周知,this的指向問題一直是JS中比較難的問題,很多時(shí)候我們都搞不清this到底指向的誰。今天,我就來給大家講一下this的指向問題。
一句話概括:誰調(diào)用this,this就指向誰。
接下來給大家舉幾個(gè)簡單的例子:
? ? ? ? var lilei = {
???????????name : "lilei",
???????????age?:?18,
???????????say?:?function()?{
???????????????console.log(`我叫${this.name},今年${this.age}`);
???????????}
???????}
???????lilei.say();? ? // 調(diào)用lilei的say方法
大家都知道上述例子中返回的結(jié)果為:“我叫l(wèi)ilei,今年18”? ??纱蠹抑肋@其中的原理是什么嗎?
首先,我們得明白一個(gè)問題,為什么此例中的say方法要獲取自己對(duì)象中的name和age屬性要加this.?
如果不加this. 會(huì)怎樣?很顯然,會(huì)報(bào)錯(cuò),因?yàn)閟ay方法的作用域中不存在name和age屬性。有朋友會(huì)說,say方法、name和age屬性不都是屬于 lilei 這個(gè)對(duì)象嘛,他們應(yīng)該是屬于同一個(gè)作用域,按理來說都可以彼此訪問啊。
這里我們得弄清楚一個(gè)問題,對(duì)象到底有沒有作用域?答案是:沒有。
為什么:因?yàn)镴S只有全局作用域(window)和局部作用域(函數(shù)內(nèi)部)2種作用域,而對(duì)象剛好兩者都不是。
所以:我們調(diào)用say方法時(shí),say方法會(huì)在他的作用域鏈中進(jìn)行尋找,到底有沒有name和age屬性,顯而易見,say的局部作用域中沒有,那么? ? 就在window中尋找,剛好window中也沒有。所以不加this.結(jié)果就會(huì)報(bào)錯(cuò)。
而我們要想訪問,就得用this,加了this 的屬性就會(huì)等待被調(diào)用,這里的say方法是被lilei調(diào)用的,按照最上面所說的,誰調(diào)用this,this就指向誰。那么這里的this.name和this.age就指的是lilei對(duì)象中的name和age屬性的值。所以,會(huì)返回 “我叫l(wèi)ilei,今年18”。
接下來,再舉個(gè)例子來應(yīng)證這句話:“誰調(diào)用this,this就指向誰”。
? ? ? ? var lilei = {
???????????name?:?"lilei",
???????????sex?:?"male",
???????????age?:?18,
???????????say?:?function()?{
???????????????console.log(`我叫${this.name},今年${this.age}`);
???????????}
????????}
???????lilei.say();? ? // 調(diào)用lilei的say方法
???????var?mike?=?{
???????????name : "mike",
???????????age?:?20
????????}
???????mike.say = lilei.say;? ? // 將lilei對(duì)象中的say方法賦給mike的say方法(mike沒有say方法就會(huì)創(chuàng)建一個(gè)say方法)
???????mike.say();? ? ? ? ? ? ? // 調(diào)用mike的say方法
? ? ? ? var say = lilei.say;? ? //將lilei對(duì)象中的say方法賦給一個(gè)新的變量
? ? ? ? say();? ? ? ? ? ? ? ? ? //調(diào)用say方法
我們先講mike.say()會(huì)返回什么?這里賦值之后,有的朋友可能會(huì)認(rèn)為,既然是lilei的say方法,那么mike的say方法應(yīng)該是指向的lilei的say方法。依然會(huì)返回“我叫l(wèi)ilei,今年18”??山Y(jié)果卻恰恰相反,返回的是“我叫mike,今年20”。
按照我們所說的口訣:“誰調(diào)用this,this就指向誰”。那么這里this指向的就是mike對(duì)象,剛好mike對(duì)象中有name和age屬性,可直接進(jìn)行調(diào)用。所以,這里返回的結(jié)果就是:“我叫mike,今年20”。
再來講最后面的say()會(huì)返回什么,這里我們是將lilei對(duì)象中的say方法賦給了say變量,如果按照上面有的朋友認(rèn)為的,那么應(yīng)該會(huì)繼承l(wèi)ilei中的say方法,返回“我叫l(wèi)ilei,今年18”。但是結(jié)果卻不盡人意,并是不。
同樣,按照我們所說的口訣,“誰調(diào)用this,this就指向誰”。那么這里的this就指向了全局window,有的朋友說為什么是全局window,這里的say() 實(shí)際上就等同于 window.say(),所以就是window調(diào)用了say方法,this就指向了window,同時(shí),say方法就會(huì)去window中找尋name和age屬性的值,但是我們這里并沒有在window全局作用域中聲明name和age屬性,因此就沒找到,所以這里返回的結(jié)果就是undefined未定義。
以上就是關(guān)于this的指向問題,可能有些地方?jīng)]講明白,希望見諒,如果有不懂的地方或者有什么意見或建議,請(qǐng)?jiān)谙路搅粞曰蛘呗?lián)系本人。
謝謝大家的觀看,希望大家多多關(guān)注我,本人會(huì)不定期為大家更新相關(guān)資源與教程。