淺析JS中的this

JS 中的this到底是什么

首先說(shuō)結(jié)論:

fn.call (context,argument[]) ,this 就是你 call 一個(gè)函數(shù)時(shí),傳入的 context。

那大家肯定有疑問(wèn),函數(shù)調(diào)用形式多鐘,如果不是這種調(diào)用形式呢?那又如何確定this呢?
接下來(lái)我們先從函數(shù)調(diào)用形式說(shuō)起

函數(shù)調(diào)用形式

JS(ES5)里面有三種函數(shù)調(diào)用形式:

fn(p1, p2) 
obj.child.method(p1, p2)
fn.call(context, p1, p2) //標(biāo)準(zhǔn)調(diào)用形式

其中,第三種調(diào)用形式,才是正常調(diào)用形式函數(shù)調(diào)用標(biāo)準(zhǔn)形式

fn.call(context, p1, p2)

其他兩種都是語(yǔ)法糖,可以等價(jià)地變?yōu)?call 形式:

fn(p1, p2) 等價(jià)于
fn.call(undefined, p1, p2)

obj.child.method(p1, p2) 等價(jià)于
obj.child.method.call(obj.child, p1, p2)

所以,我們知道不論哪種情況的函數(shù)調(diào)用,都可以轉(zhuǎn)換為標(biāo)準(zhǔn)形式:

fn.call(context, p1, p2)

如此,只要是函數(shù)調(diào)用,你就可以輕松的知道this的傳入形式。如果你的函數(shù)調(diào)用形式不是 call 形式,請(qǐng)按照「轉(zhuǎn)換代碼」將其轉(zhuǎn)換為 call 形式。

this 傳入的是什么?

在了解this 就是 call 一個(gè)函數(shù)時(shí),傳入的 context后,我們還需要了解他傳入的是什么

首先我們構(gòu)造一個(gè)監(jiān)聽函數(shù)

$div.on('click',function(){
  conlose.log('click')
  conlose.log('this')
})
click
<div></div>

在這個(gè)監(jiān)聽函數(shù)中,我們發(fā)現(xiàn),打印出this就是我們監(jiān)聽的元素
那么this是否就是這個(gè)監(jiān)聽元素嗎?實(shí)際不是這樣的

接下來(lái)我們繼續(xù)構(gòu)造一個(gè)事件委托

 $div.on('click','button',function(){
  conlose.log('click')
  conlose.log('this')
})
click
<button></button>

在這個(gè)事件委托中,打印出的this是我們點(diǎn)擊的元素(button),并不是我們監(jiān)聽的元素

那么現(xiàn)在結(jié)論出來(lái)了,this ===e.currentTaget ?

$div.on('click','button',function(e){
  conlose.log('click')
  if (this === e.currentTaget){
    conlose.log('true')
  }
})
click
true

實(shí)際證明,的確如此。

通常性看來(lái),this 在JS中是多余的,它只是為了看起來(lái)像Java而設(shè)定的

this的使用方式

在一個(gè)對(duì)象里, 可以用this表示一個(gè)對(duì)象

通常時(shí)候,其實(shí)this是多余的,我們可以直接用對(duì)象名,而不使用this。

但是,某些時(shí)候,我們并不知道對(duì)象名,這時(shí)候就不得不用this來(lái)替代了。

let module = {
  element: null,
  init: function(){
    let $div = this.element  //this.element = module.element
                             //在這里,對(duì)象名module可以用this替代
    $div.on('click','button',this.onClickButton)
    $div.on('click',function(){
      conlose.log('click')
    })
  },
  onClickButton: function(e){
    console.log('button is click')
  }
}
module.init($div) // 等同于 module.init.call(module,$div)

但是 this在一個(gè)對(duì)象中,是可以改變的

let module = {
  element: null,
  init: function(){
    let $div = this.element  
    $div.on('click','button',this.onClickButton)  //這里的this === module
  },
  onClickButton: function(e){
    console.log('button is click')
    console.log('this')  //由于觸發(fā)了click監(jiān)聽事件,這里的this已經(jīng)變成了監(jiān)聽事件的點(diǎn)擊元素button
  }
}
module.init($div) // 等同于 module.init.call(module,$div)

上例中,由于監(jiān)聽事件的this的值是指向觸發(fā)事件的元素。所以this已經(jīng)改變

可以看出,this在特定場(chǎng)景下,是會(huì)根據(jù)API的源代碼定義所改變。

那么如果我們想指定監(jiān)聽事件傳入的this是我們想要的this,怎么辦?

$div.on('click','button',function(){
  module.onClickButton.call(module,e)  //這里我們強(qiáng)制指定了傳入this值為module
})  

$div.on('click','button',this.onClickButton.bind(this))

我們還可以用bind 來(lái)實(shí)現(xiàn)

$div.on('click','button',this.onClickButton.bind(this))

總結(jié)

  1. this 就是你 call 一個(gè)函數(shù)時(shí),傳入的 context
  2. 如果函數(shù)調(diào)用形式不是 call 形式,請(qǐng)將其轉(zhuǎn)換為 call 形式
  3. 在一個(gè)對(duì)象里, 可以用this表示一個(gè)對(duì)象
  4. 在監(jiān)聽事件里,this的值是指向觸發(fā)事件的元素
  5. 任何函數(shù)都可以強(qiáng)制指定傳入的this,也可以使用bind來(lái)改變默認(rèn)傳入this
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式。簡(jiǎn)單...
    舟漁行舟閱讀 8,115評(píng)論 2 17
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無(wú)需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性。 1....
    LaBaby_閱讀 1,262評(píng)論 0 1
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無(wú)需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性。 1....
    LaBaby_閱讀 1,494評(píng)論 0 2
  • 【我的閱讀】《直心真實(shí),老虎為徒》 牛頭山慧忠禪師被稱為山主,可能是因?yàn)樗芘c萬(wàn)物溝通的緣故。 當(dāng)時(shí)政府劃給寺院二...
    一畝岐江閱讀 517評(píng)論 1 3
  • 月落烏啼霜滿天,江楓漁火對(duì)愁眠 姑蘇城外寒山寺,夜半鐘聲到客船 冬日的陽(yáng)光是恩賜,我被這恩賜眷顧,在這暖暖陽(yáng)光下,...
    emilychan閱讀 781評(píng)論 0 0

友情鏈接更多精彩內(nèi)容