|
下圖是在ASP.NET中為button掛上客戶端onclick事件的兩種辦法:圖中的2和3/1。 結(jié)果發(fā)現(xiàn)兩種方式調(diào)用同樣一個(gè)函數(shù)clickMe,this卻不一樣。
如果采用3或1的做法,那么點(diǎn)擊button1后將alert出[object DOMWindow];而采用2的做法,將alert出 [object HTMLInputElement](在chrome下測(cè)試。)
顯然,在1的做法中,this指向DOMWindow,也就是全局的object——global;而2的做法中,this指向Button1這個(gè)元素。
為什么呢?
(注:對(duì)于3這種通過(guò)Attribute來(lái)聲明處理程序的方式,button的onclick不是指向clickMe函數(shù),而是指向一個(gè)被自動(dòng)創(chuàng)建的匿名函數(shù),該匿名函數(shù)以Attribute的值(也就是"clickMe();")作為函數(shù)體——也就是等價(jià)于1。)
簡(jiǎn)單的答案
基于類(lèi)的OO語(yǔ)言(比如C#)中,函數(shù)總是聲明在一個(gè)類(lèi)中,函數(shù)內(nèi)部的this指向該類(lèi)的當(dāng)前實(shí)例。而JS中,函數(shù)是第一等公民(它不會(huì)聲明為別的東西的一部分),所以this跟函數(shù)是如何聲明的無(wú)關(guān),跟函數(shù)是怎么被調(diào)用的有關(guān)。
方式1和2對(duì)clickMe的調(diào)用,不同之處在于:1中clickMe是被button1.onclick所指向的函數(shù)調(diào)用的,2中clickMe是作為button1.onclick屬性直接調(diào)用的。因此對(duì)于clickMe函數(shù),1中的this指向“擁有”clickMe函數(shù)的對(duì)象——global(DOMWindow),而2中的this指向“擁有”onclick屬性的對(duì)象——button1。
可惜對(duì)像我這種寫(xiě)JS寫(xiě)的不多的人來(lái)說(shuō),總是記不住這個(gè)簡(jiǎn)單答案,因?yàn)樗桓嬖V我what,沒(méi)有告訴我why。本文試圖從ECMAScript官方文檔出發(fā),從原理上說(shuō)明:在不同的場(chǎng)合中,函數(shù)的this到底是什么?
call和apply
首先明確一點(diǎn),在最正常的情況下,我們這樣調(diào)用:Func(),這時(shí)this是由JavaScript來(lái)確定的,這也是本篇要研究的主題。而如果用Func.call(thisArg, arg1, arg2, ...)或者Func.apply(thisArg, [arg1, arg2, ...])來(lái)調(diào)用時(shí),this是我們自己傳進(jìn)去的(作為call或apply的第一個(gè)參數(shù))。如果我們不傳this進(jìn)去,或者傳null進(jìn)去,會(huì)怎樣?這時(shí)this將會(huì)是global object。
函數(shù)作為構(gòu)造器時(shí)的this
先從簡(jiǎn)單的說(shuō)起。所謂構(gòu)造器,就是用new關(guān)鍵字來(lái)調(diào)用函數(shù),在這篇關(guān)于new關(guān)鍵字的玄機(jī)的文章中有說(shuō)到??聪旅娴淖⑨?zhuān)梢灾溃珹函數(shù)里的this這時(shí)就是a。
function A() {this.x = 1;}var a = new A(); //這行代碼大概等價(jià)于下面兩行
it知識(shí)庫(kù):我的JavaScript之旅——this到底是啥?,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。