JS 裡為什麼會有 this
1、需求
假設我們有一個對象
var person = { name: 'Frank', age: 18, phone: '13812345678', sayHi: function(){ // 待補充 }, sayBye: function(){ // 待補充 } }
這個 person
對象有 name
和 age
屬性,還有一個 sayHi
方法,現在的需求是:
調用
person.sayHi(...)
,打印出「你好,我是Frank
,今年 18 歲」。
調用person.sayBuy(...)
,打印出「再見,記得我叫Frank
哦,想約我的話打電話給我,我的電話是 13812345678」
需
求就是這麼簡單,通過達成這個需求,我們就能理解 this
的本質。
2、方案
var person = { ... sayHi: function(name, age){ console.log('你好,我是 ${name},今年 ${age} 歲') }, sayBye: function(name, phone){ console.log('再見,記得我叫 ${name} 哦,想約我的話打電話給我,我的電話是 ${phone}') } }
調用方式是
person.sayHi(person.name, person.age) person.sayBye(person.name, person.phone)
別急,我知道這代碼很傻,接下來改進。
3、第一次改進
上面方法中,每次都要在調用的時候自行選擇 person.name
作為參數,真的很傻,不如直接傳入一個 person
,代碼如下:
var person = { ... sayHi: function(self){ console.log('你好,我是 ${self.name},今年 ${self.age} 歲') }, sayBye: function(self){ console.log('再見,記得我叫 ${self.name} 哦,想約我的話打電話給我,我的電話是 ${self.phone}') } }
調用方式是
person.sayHi(person) person.sayBye(person)
稍微好一點瞭,但是這代碼依然很傻。
為什麼不能把參數裡的 person
省掉,變成 person.sayHi()
就好瞭。
4、加糖
開發者最想要的調用方式是 person.sayHi()
那麼問題來瞭,如果 ,
person.sayHi()
沒有實參,person.sayHi
函數是如何接收到 person
的呢?
- 方法1:依然把第一個參數
self
當做person
,這樣形參就會永遠比實參多出一個 self - 方法2:隱藏
self
,然後用關鍵字this
來訪問self
。
JS 之父選擇瞭方法2,用 this
訪問 self
。Python
之父選擇瞭方法1,留下 self 作為第一個參數。
過程如下:
// 用 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}') } }
現在輪到新手疑惑瞭,這個 this
到底是個啥玩意兒?從哪來的呀?
實際上
this 是隱藏的第一個形參。在你調用 person.sayHi()
時,這個 person
會「變成」 this
。
6、存在問題
很多 JS 高手不屑於用 this
,覺得 this 不夠單純。所以 JS 之父給高手們準備瞭無糖的 .call
方法。
person.sayHi.call(person)
就等價於 person.sayHi()
.call 的第一個參數就是顯式的 person
,沒有任何語法糖。
所以高手一般用 obj.fn.call(null,1,2,3)
來手動禁用 this
。
這樣一來 person.sayHi.call
的參數其實可以是任何對象。
也就是說 person.sayHi
雖然是 person
的方法,但是是可以調用在任何對象上的。
7、對象與函數
JS
沒有類沒有方法,隻有對象和函數。
JS
加瞭 class
關鍵字之後,勉強弄出來一個假的類。
this
是連接對象和函數的橋梁。
相比於 JS
,我更喜歡 Python
的方式,不使用 this 關鍵字,而是使用 self
形參,更易懂。
到此這篇關於JS 裡為什麼會有 this的文章就介紹到這瞭,更多相關JS 裡為什麼會有 this內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 原生Javascript實現繼承方式及其優缺點詳解
- 一文搞懂JavaScript中的this綁定規則
- JS創建對象的四種方式
- Javascript的原型和原型鏈你瞭解嗎
- JavaScript原型鏈及常見的繼承方法