js中this原理

一拿撩、問題的由來

學(xué)懂 JavaScript 語言衣厘,一個標(biāo)志就是理解下面兩種寫法,可能有不一樣的結(jié)果压恒。

var????obj={foo:function(){

????????};

var????foo????=????obj.foo;

// 寫法一

obj.foo()

// 寫法二foo()

上面代碼中影暴,雖然obj.foo和foo指向同一個函數(shù)怖亭,但是執(zhí)行結(jié)果可能不一樣。請看下面的例子坤检。

var obj={foo:function(){

????console.log(this.bar)},

????bar:1};

var foo=obj.foo;

varbar=2;

obj.foo() // 1

foo() // 2

這種差異的原因兴猩,就在于函數(shù)體內(nèi)部使用了this關(guān)鍵字。很多教科書會告訴你早歇,this指的是函數(shù)運行時所在的環(huán)境。對于obj.foo()來說箭跳,foo運行在obj環(huán)境,所以this指向obj谱姓;對于foo()來說借尿,foo運行在全局環(huán)境,所以this指向全局環(huán)境屉来。所以路翻,兩者的運行結(jié)果不一樣。

這種解釋沒錯茄靠,但是教科書往往不告訴你茂契,為什么會這樣?也就是說慨绳,函數(shù)的運行環(huán)境到底是怎么決定的掉冶?舉例來說脐雪,為什么obj.foo()就是在obj環(huán)境執(zhí)行,而一旦var foo = obj.foo战秋,foo()就變成在全局環(huán)境執(zhí)行?

本文就來解釋 JavaScript 這樣處理的原理获询。理解了這一點涨岁,你就會徹底理解this的作用吉嚣。

二、內(nèi)存的數(shù)據(jù)結(jié)構(gòu)

JavaScript 語言之所以有this的設(shè)計尝哆,跟內(nèi)存里面的數(shù)據(jù)結(jié)構(gòu)有關(guān)系秉撇。

varobj={foo:5};

上面的代碼將一個對象賦值給變量obj琐馆。JavaScript 引擎會先在內(nèi)存里面,生成一個對象{ foo: 5 }瘦麸,然后把這個對象的內(nèi)存地址賦值給變量obj谁撼。

也就是說厉碟,變量obj是一個地址(reference)。后面如果要讀取obj.foo屠缭,引擎先從obj拿到內(nèi)存地址,然后再從該地址讀出原始的對象呵曹,返回它的foo屬性。

原始的對象以字典結(jié)構(gòu)保存奄喂,每一個屬性名都對應(yīng)一個屬性描述對象。舉例來說砍聊,上面例子的foo屬性背稼,實際上是以下面的形式保存的。

{foo:{[[value]]:5[[writable]]:true[[enumerable]]:true[[configurable]]:true}}

注意词疼,foo屬性的值保存在屬性描述對象的value屬性里面。

三贰盗、函數(shù)

這樣的結(jié)構(gòu)是很清晰的许饿,問題在于屬性的值可能是一個函數(shù)舵盈。

varobj={foo:function(){}};

這時,引擎會將函數(shù)單獨保存在內(nèi)存中秽晚,然后再將函數(shù)的地址賦值給foo屬性的value屬性。

{foo:{[[value]]:函數(shù)的地址...}}

由于函數(shù)是一個單獨的值赴蝇,所以它可以在不同的環(huán)境(上下文)執(zhí)行。

varf=function(){};varobj={f:f};// 單獨執(zhí)行f()// obj 環(huán)境執(zhí)行obj.f()

四、環(huán)境變量

JavaScript 允許在函數(shù)體內(nèi)部劲蜻,引用當(dāng)前環(huán)境的其他變量。

varf=function(){console.log(x);};

上面代碼中先嬉,函數(shù)體里面使用了變量x。該變量由運行環(huán)境提供疫蔓。

現(xiàn)在問題就來了,由于函數(shù)可以在不同的運行環(huán)境執(zhí)行鳄袍,所以需要有一種機制绢要,能夠在函數(shù)體內(nèi)部獲得當(dāng)前的運行環(huán)境(context)拗小。所以,this就出現(xiàn)了哀九,它的設(shè)計目的就是在函數(shù)體內(nèi)部,指代函數(shù)當(dāng)前的運行環(huán)境阅束。

varf=function(){console.log(this.x);}

上面代碼中,函數(shù)體里面的this.x就是指當(dāng)前運行環(huán)境的x息裸。

varf=function(){console.log(this.x);}varx=1;varobj={f:f,x:2,};// 單獨執(zhí)行f() // 1// obj 環(huán)境執(zhí)行obj.f() // 2

上面代碼中蝇更,函數(shù)f在全局環(huán)境執(zhí)行呼盆,this.x指向全局環(huán)境的x。

在obj環(huán)境執(zhí)行访圃,this.x指向obj.x。

回到本文開頭提出的問題腿时,obj.foo()是通過obj找到foo,所以就是在obj環(huán)境執(zhí)行批糟。一旦var foo = obj.foo,變量foo就直接指向函數(shù)本身跃赚,所以foo()就變成在全局環(huán)境執(zhí)行性湿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市满败,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌算墨,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件净嘀,死亡現(xiàn)場離奇詭異,居然都是意外死亡挖藏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門膜眠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宵膨,你說我怎么就攤上這事架谎”脔铮” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵捎琐,是天一觀的道長。 經(jīng)常有香客問我瑞凑,道長在塔,這世上最難降的妖魔是什么拨黔? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任篱蝇,我火速辦了婚禮,結(jié)果婚禮上徽曲,老公的妹妹穿的比我還像新娘。我一直安慰自己秃臣,他們只是感情好涧衙,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著弧哎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪撤嫩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天序攘,我揣著相機與錄音茴她,去河邊找鬼程奠。 笑死,一個胖子當(dāng)著我的面吹牛瞄沙,可吹牛的內(nèi)容都是我干的己沛。 我是一名探鬼主播帕识,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼肮疗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起伪货,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碱呼,沒想到半個月后蒙挑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體愚臀,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年姑裂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舶斧。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖茴厉,靈堂內(nèi)的尸體忽然破棺而出泽台,到底是詐尸還是另有隱情,我是刑警寧澤怀酷,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站胰坟,受9級特大地震影響因篇,放射性物質(zhì)發(fā)生泄漏笔横。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一吹缔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厢塘,春花似錦茶没、人聲如沸晚碾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笛求。三九已至糕簿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間懂诗,已是汗流浹背蜂嗽。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工殃恒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人离唐。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像侯繁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子贮竟,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

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