javascript中this的指向

在面向?qū)ο蟮恼Z(yǔ)言中(例如Java,C#等),this含義是明確且具體的神帅,即指向當(dāng)前對(duì)象再姑。一般在編譯期綁定。而在javascript中找御,this是動(dòng)態(tài)綁定的元镀,它可以是全局對(duì)象、當(dāng)前對(duì)象或者任意對(duì)象霎桅,這完全取決于函數(shù)的調(diào)用方式栖疑。這就導(dǎo)致了this具備了多重含義,可以使得javascript更靈活的使用滔驶。但是遇革,帶來(lái)了靈活性的同時(shí)也會(huì)給我們初學(xué)者帶來(lái)不少困惑。

全局環(huán)境中的this

console.log(this);

總結(jié):在全局作用域中它的 this 執(zhí)行當(dāng)前的全局對(duì)象(瀏覽器端是 Window揭糕,node 中是 global)

例子1:

function a(){

var user = "qintengbo";

console.log(this.user); //undefined

console.log(this); //Window

}

a();

this最終指向的是調(diào)用它的對(duì)象,這里的函數(shù)a實(shí)際是被Window對(duì)象所點(diǎn)出來(lái)的萝快,下面的代碼就可以證明。

function a(){

var user = "qintengbo";

console.log(this.user); //undefined

console.log(this);  //Window

}

window.a();

和前面代碼一樣著角,其實(shí)alert也是window的一個(gè)屬性揪漩,也是window點(diǎn)出來(lái)的。

例子2:

var o = {

user:"qintengbo",

fn:function() {

console.log(this.user); ?//qintengbo

}

}

o.fn();

這里的this指向的是對(duì)象o吏口,因?yàn)槟阏{(diào)用這個(gè)fn是通過(guò)o.fn()執(zhí)行的奄容,那自然指向就是對(duì)象o冰更。

this的指向在函數(shù)定義的時(shí)候是確定不了的,只有函數(shù)執(zhí)行的時(shí)候才能確定this到底指向誰(shuí)嫩海,實(shí)際上this的最終指向的是那個(gè)調(diào)用它的對(duì)象.

其實(shí)例子1和例子2說(shuō)的并不夠準(zhǔn)確冬殃,下面這個(gè)例子就可以推翻上面的理論。

如果要徹底的搞懂this必須看接下來(lái)的幾個(gè)例子叁怪。

例子3:

var o = {

user:"qintengbo",

fn:function() {

console.log(this.user); //qintengbo

}

}

window.o.fn();

這段代碼和上面的那段代碼幾乎是一樣的审葬,但是這里的this為什么不是指向window,如果按照上面的理論奕谭,最終this指向的是調(diào)用它的對(duì)象涣觉。

var o = {

a:10,

b:{

a:12,

fn:function(){

console.log(this.a); //12

}

}

}

o.b.fn();

這里同樣也是對(duì)象o點(diǎn)出來(lái)的,但是同樣this并沒(méi)有執(zhí)行它血柳,那你肯定會(huì)說(shuō)我一開(kāi)始說(shuō)的那些不就都是錯(cuò)誤的嗎官册?其實(shí)也不是,只是一開(kāi)始說(shuō)的不準(zhǔn)確难捌。

情況1:如果一個(gè)函數(shù)中有this膝宁,但是它沒(méi)有被上一級(jí)的對(duì)象所調(diào)用,那么this指向的就是window根吁,這里需要說(shuō)明的是在js的嚴(yán)格版中this指向的不是window员淫。

情況2:如果一個(gè)函數(shù)中有this,這個(gè)函數(shù)有被上一級(jí)的對(duì)象所調(diào)用击敌,那么this指向的就是上一級(jí)的對(duì)象介返。

情況3:如果一個(gè)函數(shù)中有this,這個(gè)函數(shù)中包含多個(gè)對(duì)象沃斤,盡管這個(gè)函數(shù)是被最外層的對(duì)象所調(diào)用圣蝎,this指向的也只是它上一級(jí)的對(duì)象。

證明情況3的說(shuō)法:

var o = {

a:10,

b:{

// a:12,

fn:function(){

console.log(this.a); //undefined

}

}

}

o.b.fn();

盡管對(duì)象b中沒(méi)有屬性a衡瓶,這個(gè)this指向的也是對(duì)象b徘公,因?yàn)閠his只會(huì)指向它的上一級(jí)對(duì)象,不管這個(gè)對(duì)象中有沒(méi)有this要的東西哮针。

特殊情況例子4:

var o = {

a:10,

b:{

a:12,

fn:function(){

console.log(this.a); //undefined

console.log(this); //window

}

}

}

var j = o.b.fn;

j();

這里this指向的是window步淹,是不是有些蒙了?

其實(shí)是因?yàn)槟銢](méi)有理解一句話诚撵,這句話同樣至關(guān)重要:

this永遠(yuǎn)指向的是最后調(diào)用它的對(duì)象,也就是看它執(zhí)行的時(shí)候是誰(shuí)調(diào)用的键闺。

嚴(yán)格模式 ‘use strict’下的this

'use strict';

function test() {

console.log(this);

};

test();

// undefined

原因:this 并不會(huì)指向全局寿烟,而是 undefined,這樣的做法是為了消除 js 中一些不嚴(yán)謹(jǐn)?shù)男袨?/p>

jq中的this和$(this):

$("button").click(function(){

console.log(this);

console.log($(this));

});

$(this)是jquery對(duì)象辛燥,能調(diào)用jquery的方法筛武,例如click(), keyup()缝其。

而this,則是html元素對(duì)象,能調(diào)用元素屬性徘六,例如this.id,this.value内边。

例如假設(shè)已經(jīng)使得this和$(this)都指向了input對(duì)象了,若要獲得input的值,可以this.value待锈,但$(this)就得$(this).val()漠其。


var obj = {

name: 'qiutc',

foo: function() {

console.log(this);

},

foo2: function() {

console.log(this);

setTimeout(this.foo, 1000);

}

}

obj.foo2();

現(xiàn)象:兩次打印的this不一樣

可以這么這么解決:利用 閉包 的特性來(lái)處理

var obj = {

name: 'qiutc',

foo: function() {

console.log(this);

},

foo2: function() {

console.log(this);

var _this = this;

setTimeout(function() {

console.log(this); ?// Window

console.log(_this); ?// Object {name: "qiutc"}

}, 1000);

}

}

obj.foo2();

可以看到直接用 this 仍然是 Window;因?yàn)?foo2 中的 this 是指向 obj竿音,我們可以先用一個(gè)變量 _this 來(lái)儲(chǔ)存和屎,然后在回調(diào)函數(shù)中使用 _this,就可以指向當(dāng)前的這個(gè)對(duì)象了

執(zhí)行這段代碼我們會(huì)發(fā)現(xiàn)兩次打印出來(lái)的 this 是不一樣的:

第一次是 foo2 中直接打印 this春瞬,這里指向 obj 這個(gè)對(duì)象柴信,我們毋庸置疑;

但是在 setTimeout 中執(zhí)行的 this.foo 宽气,卻指向了全局對(duì)象随常,這里不是把它當(dāng)作函數(shù)的方法使用嗎?這一點(diǎn)經(jīng)常讓很多初學(xué)者疑惑萄涯;

其實(shí)绪氛,setTimeout 也只是一個(gè)函數(shù)而已,函數(shù)必然有可能需要參數(shù)窃判,我們把 this.foo 當(dāng)作一個(gè)參數(shù)傳給 setTimeout 這個(gè)函數(shù)钞楼,就像它需要一個(gè) fun 參數(shù),在傳入?yún)?shù)的時(shí)候袄琳,其實(shí)做了個(gè)這樣的操作 fun = this.foo询件,看到?jīng)]有,這里我們直接把 fun 指向 this.foo 的引用唆樊;執(zhí)行的時(shí)候其實(shí)是執(zhí)行了 fun() 所以已經(jīng)和 obj 無(wú)關(guān)了宛琅,它是被當(dāng)作普通函數(shù)直接調(diào)用的,因此 this 指向全局對(duì)象逗旁。

這個(gè)問(wèn)題是很多異步回調(diào)函數(shù)中普遍會(huì)碰到的嘿辟;


百度14年的筆試題:

var myObject = {

foo:"bar",

func: function() {

var self = this;

console.log("outer func: this.foo = " + this.foo);

console.log("outer func: self.foo = " + self.foo);

(function (){

console.log("inner func: this.foo = " + this.foo);

console.log("inner func: self.foo = " + self.foo);

}());

}

}

myObject.func();

這里分別會(huì)打印出什么?


問(wèn)題:當(dāng)this遇到return時(shí)會(huì)發(fā)生什么片效?

如果返回值是一個(gè)對(duì)象红伦,那么this指向的就是那個(gè)返回的對(duì)象,如果返回值不是一個(gè)對(duì)象那么this還是指向函數(shù)的實(shí)例淀衣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昙读,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子膨桥,更是在濱河造成了極大的恐慌蛮浑,老刑警劉巖唠叛,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異沮稚,居然都是意外死亡艺沼,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)蕴掏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)障般,“玉大人,你說(shuō)我怎么就攤上這事囚似∈B#” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵饶唤,是天一觀的道長(zhǎng)徐伐。 經(jīng)常有香客問(wèn)我,道長(zhǎng)募狂,這世上最難降的妖魔是什么办素? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮祸穷,結(jié)果婚禮上性穿,老公的妹妹穿的比我還像新娘。我一直安慰自己雷滚,他們只是感情好需曾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著祈远,像睡著了一般呆万。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上车份,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天谋减,我揣著相機(jī)與錄音,去河邊找鬼扫沼。 笑死出爹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缎除。 我是一名探鬼主播严就,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼器罐!你這毒婦竟也來(lái)了梢为?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抖誉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體衰倦,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袒炉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了樊零。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片我磁。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖驻襟,靈堂內(nèi)的尸體忽然破棺而出夺艰,到底是詐尸還是另有隱情,我是刑警寧澤沉衣,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布郁副,位于F島的核電站,受9級(jí)特大地震影響豌习,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肥隆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一既荚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧栋艳,春花似錦恰聘、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至旬昭,卻和暖如春一屋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脓匿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工压鉴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骤坐。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓绪杏,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親纽绍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蕾久,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Javascript 中的 this,有時(shí)候讓人迷惑拌夏,所以總結(jié)了一下關(guān)于this指向的問(wèn)題僧著。 在函數(shù)中 this ...
    lxt410725閱讀 460評(píng)論 0 1
  • 作者:伯樂(lè)在線專欄作者 - 追夢(mèng)子鏈接:http://web.jobbole.com/88264/ 首先必須要說(shuō)的...
    心至靜行至遠(yuǎn)閱讀 340評(píng)論 0 1
  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品履因,去做同樣的事情,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式盹愚。簡(jiǎn)單...
    舟漁行舟閱讀 7,718評(píng)論 2 17
  • 單例模式 適用場(chǎng)景:可能會(huì)在場(chǎng)景中使用到對(duì)象栅迄,但只有一個(gè)實(shí)例,加載時(shí)并不主動(dòng)創(chuàng)建皆怕,需要時(shí)才創(chuàng)建 最常見(jiàn)的單例模式毅舆,...
    Obeing閱讀 2,056評(píng)論 1 10
  • 之所以不叫海底世界,是因?yàn)橹挥幸粭l魚(yú)愈腾,哈哈憋活,寂寞嗎?畫(huà)畫(huà)就是一件寂寞的事虱黄,但當(dāng)作品完成悦即,感覺(jué)自己創(chuàng)造了一個(gè)新事物,...
    語(yǔ)靜然閱讀 3,098評(píng)論 4 8