JS 里為什么會(huì)有 this
1、需求
假設(shè)我們有一個(gè)對(duì)象
var person = { name: 'Frank', age: 18, phone: '13812345678', sayHi: function(){ // 待補(bǔ)充 }, sayBye: function(){ // 待補(bǔ)充 } }
這個(gè) person
對(duì)象有 name
和 age
屬性,還有一個(gè) sayHi
方法,現(xiàn)在的需求是:
調(diào)用
person.sayHi(...)
,打印出「你好,我是Frank
,今年 18 歲」。
調(diào)用person.sayBuy(...)
,打印出「再見(jiàn),記得我叫Frank
哦,想約我的話打電話給我,我的電話是 13812345678」
需
求就是這么簡(jiǎn)單,通過(guò)達(dá)成這個(gè)需求,我們就能理解 this
的本質(zhì)。
2、方案
var person = { ... sayHi: function(name, age){ console.log('你好,我是 ${name},今年 ${age} 歲') }, sayBye: function(name, phone){ console.log('再見(jiàn),記得我叫 ${name} 哦,想約我的話打電話給我,我的電話是 ${phone}') } }
調(diào)用方式是
person.sayHi(person.name, person.age) person.sayBye(person.name, person.phone)
別急,我知道這代碼很傻,接下來(lái)改進(jìn)。
3、第一次改進(jìn)
上面方法中,每次都要在調(diào)用的時(shí)候自行選擇 person.name
作為參數(shù),真的很傻,不如直接傳入一個(gè) person
,代碼如下:
var person = { ... sayHi: function(self){ console.log('你好,我是 ${self.name},今年 ${self.age} 歲') }, sayBye: function(self){ console.log('再見(jiàn),記得我叫 ${self.name} 哦,想約我的話打電話給我,我的電話是 ${self.phone}') } }
調(diào)用方式是
person.sayHi(person) person.sayBye(person)
稍微好一點(diǎn)了,但是這代碼依然很傻。
為什么不能把參數(shù)里的 person
省掉,變成 person.sayHi()
就好了。
4、加糖
開(kāi)發(fā)者最想要的調(diào)用方式是 person.sayHi()
那么問(wèn)題來(lái)了,如果 ,
person.sayHi()
沒(méi)有實(shí)參,person.sayHi
函數(shù)是如何接收到 person
的呢?
- 方法1:依然把第一個(gè)參數(shù)
self
當(dāng)做person
,這樣形參就會(huì)永遠(yuǎn)比實(shí)參多出一個(gè) self - 方法2:隱藏
self
,然后用關(guān)鍵字this
來(lái)訪問(wèn)self
。
JS 之父選擇了方法2,用 this
訪問(wèn) self
。Python
之父選擇了方法1,留下 self 作為第一個(gè)參數(shù)。
過(guò)程如下:
// 用 this 之前: sayHi: function(self){ console.log('你好,我是 ${self.name},今年 ${self.age} 歲') } // 用 this 之后: sayHi: function(){ // this 就是 self console.log('你好,我是 ${this.name},今年 ${this.age} 歲') }
5、費(fèi)解
用了 this 之后,完整代碼如下:
var person = { name: 'Frank', age: 18, phone: '13812345678', sayHi: function(){ console.log('你好,我是 ${this.name},今年 ${this.age} 歲') }, sayBye: function(){ console.log('再見(jiàn),記得我叫 ${this.name} 哦,想約我的話打電話給我,我的電話是 ${this.phone}') } }
現(xiàn)在輪到新手疑惑了,這個(gè) this
到底是個(gè)啥玩意兒?從哪來(lái)的呀?
實(shí)際上
this 是隱藏的第一個(gè)形參。在你調(diào)用 person.sayHi()
時(shí),這個(gè) person
會(huì)「變成」 this
。
6、存在問(wèn)題
很多 JS 高手不屑于用 this
,覺(jué)得 this 不夠單純。所以 JS 之父給高手們準(zhǔn)備了無(wú)糖的 .call
方法。
person.sayHi.call(person)
就等價(jià)于 person.sayHi()
.call 的第一個(gè)參數(shù)就是顯式的 person
,沒(méi)有任何語(yǔ)法糖。
所以高手一般用 obj.fn.call(null,1,2,3)
來(lái)手動(dòng)禁用 this
。
這樣一來(lái) person.sayHi.call
的參數(shù)其實(shí)可以是任何對(duì)象。
也就是說(shuō) person.sayHi
雖然是 person
的方法,但是是可以調(diào)用在任何對(duì)象上的。
7、對(duì)象與函數(shù)
JS
沒(méi)有類(lèi)沒(méi)有方法,只有對(duì)象和函數(shù)。
JS
加了 class
關(guān)鍵字之后,勉強(qiáng)弄出來(lái)一個(gè)假的類(lèi)。
this
是連接對(duì)象和函數(shù)的橋梁。
相比于 JS
,我更喜歡 Python
的方式,不使用 this 關(guān)鍵字,而是使用 self
形參,更易懂。
到此這篇關(guān)于JS 里為什么會(huì)有 this的文章就介紹到這了,更多相關(guān)JS 里為什么會(huì)有 this內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
axios進(jìn)度條onDownloadProgress函數(shù)total參數(shù)undefined解決分析
這篇文章主要介紹了axios進(jìn)度條onDownloadProgress函數(shù)total參數(shù)undefined解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07微信小程序獲取用戶(hù)openId的實(shí)現(xiàn)方法
這篇文章主要介紹了微信小程序獲取用戶(hù)openId的實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下2017-05-05高級(jí)前端必會(huì)的package.json字段知識(shí)詳解
這篇文章主要為大家介紹了高級(jí)前端必會(huì)的package.json字段知識(shí)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07JS前端使用canvas動(dòng)態(tài)繪制函數(shù)曲線示例詳解
這篇文章主要為大家介紹了JS前端使用canvas畫(huà)函數(shù)曲線的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08MutationObserver在頁(yè)面水印實(shí)現(xiàn)起到的作用詳解
這篇文章主要為大家介紹了MutationObserver在實(shí)現(xiàn)頁(yè)面水印所起到的作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07JSON stringify及parse方法實(shí)現(xiàn)數(shù)據(jù)深拷貝
這篇文章主要為大家介紹了JSON.stringify遞歸及JSON.parse有限狀態(tài)自動(dòng)機(jī)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08