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