javascript:作用域鏈淺析

前言

為可以大概了解作用域鏈?zhǔn)莻€(gè)什么東西,本文著重說明作用域鏈秀菱,盡量不引入其他的概念柿菩。

變量對(duì)象

在說作用域鏈前戚嗅,先簡(jiǎn)單地說明變量對(duì)象,畢竟是作用域鏈的核心組成枢舶。每個(gè)函數(shù)內(nèi)部都會(huì)定義變量懦胞,會(huì)定義函數(shù),在全局環(huán)境下也會(huì)定義函數(shù)凉泄、變量躏尉。對(duì)應(yīng)的區(qū)域都會(huì)有一個(gè)特殊對(duì)象,這個(gè)對(duì)象就會(huì)存放對(duì)應(yīng)區(qū)域的變量后众、函數(shù)胀糜,這個(gè)特殊的對(duì)象就是變量對(duì)象。所以說全局環(huán)境有和全局環(huán)境對(duì)應(yīng)的變量對(duì)象蒂誉,每個(gè)函數(shù)內(nèi)部也有一個(gè)與之對(duì)應(yīng)的變量對(duì)象教藻,不如下面的代碼:

<script>
  var a = 1;
  var b = [1, 2, 3, 4, 5];
  function fn(isShow){
    var gihubLink = 'https://github.com/issaxite';
    if(isShow) {
      console.log(githubLink);
    } else {
      console.log('issax');
    }
  }
</script>

上面的代碼中,

  • 全局環(huán)境的變量對(duì)象存儲(chǔ)的是:a, b, fn
  • fn函數(shù)的變量對(duì)象存儲(chǔ)的是:isShow,gihubLink右锨;你可以看見括堤,fn函數(shù)的變量對(duì)象沒有包含全局環(huán)境定義的變量和函數(shù)
作用域鏈

為什么要說變量對(duì)象呢?因?yàn)樽饔糜蜴溇褪怯勺兞繉?duì)象組成绍移,作用域鏈?zhǔn)且粋€(gè)由變量對(duì)象組成的列表悄窃,一個(gè)有序,只能由頭開始逐個(gè)往尾訪問的列表(說是列表其實(shí)更應(yīng)該說是鏈表蹂窖,先不要在意這個(gè)概念)轧抗。
并且作用域鏈和變量對(duì)象有一個(gè)共同的特點(diǎn):每個(gè)區(qū)域都會(huì)有一個(gè)與之對(duì)象對(duì)的。比如說上面的代碼中恼策,全局環(huán)境有一個(gè)與之對(duì)應(yīng)的變量對(duì)象鸦致,也有一個(gè)和全局環(huán)境對(duì)應(yīng)的作用域鏈潮剪;fn函數(shù)也是如此。

那么作用域鏈?zhǔn)怯心男┳兞繉?duì)象組成呢分唾?

我們先看下圖:



由上圖應(yīng)該可以看出抗碰,作用域鏈由當(dāng)前區(qū)域的變量對(duì)象作為開頭,然后是逐層往外直至全局環(huán)境的變量對(duì)象組成如上圖一樣的列表绽乔,這就是作用域鏈弧蝇,并且如上文所說,每個(gè)區(qū)域都有這樣一個(gè)與之對(duì)應(yīng)的作用域鏈折砸。比如下面的代碼:

<script>
  var a = 1;
  var b = [1, 2, 3, 4, 5];
  function fn(isShow){
    var gihubLink = 'https://github.com/issaxite';
    function fn1(param1, param2){
        var mailLink = 'issaxite@gmail.com';
    }
  }
</script>
  • fn1函數(shù)的作用域鏈:


  • fn的作用域鏈:


  • 全局環(huán)境的作用域鏈


那么作用域鏈的作用是什么看疗?
jser都應(yīng)該有這樣的體驗(yàn),在函數(shù)內(nèi)部可以訪問到外部區(qū)域的變量和函數(shù)睦授,而在外部區(qū)域訪問不了函數(shù)內(nèi)定義的變量:

<script>
  var a = 1;
  var b = 2;
  function fn(){
    var c = 3;
    console.log(a, b, c)
  }
  console.log(c);
</script>


如上所示两芳,fn函數(shù)內(nèi)部可以訪問到外層區(qū)域(全局環(huán)境)的變量,為什么可以去枷,就是因?yàn)閒n函數(shù)的作用域鏈怖辆,在變量調(diào)用的時(shí)候(在fn就是訪問c變量的時(shí)候),會(huì)在當(dāng)前作用域鏈的頭部開始往尾部删顶,依次在變量對(duì)象中查詢對(duì)應(yīng)的變量竖螃,找到即返回,不再繼續(xù)查詢逗余,這個(gè)也是內(nèi)層同名變量比外層同名變量?jī)?yōu)先級(jí)更高的原因特咆,這個(gè)查詢的過程叫做變量解析,也叫標(biāo)識(shí)符解析录粱,console.log(c);會(huì)拋出異常就是因?yàn)槿汁h(huán)境的作用域鏈中的變量對(duì)象沒有該變量腻格。

結(jié)語

正如本文開頭所說,本文僅是淺析作用域鏈关摇,一些相關(guān)概念都被隱掉了荒叶,比如說上文說的“區(qū)域“,應(yīng)該說是作用域或執(zhí)行環(huán)境输虱,這兩個(gè)概念其實(shí)說的不是很明確些楣,比如說執(zhí)行環(huán)境,在《javascript高級(jí)程序設(shè)計(jì)》的4.2中有說到宪睹,簡(jiǎn)直堪稱極具迷惑性愁茁,標(biāo)題更加是醉”執(zhí)行環(huán)境和作用域“,然而基本沒有談到作用域亭病。作用域在《javascript權(quán)威指南》的3.10中倒是說的挺多鹅很,還分變量作用域和函數(shù)作用域。不過啊罪帖,要是拘泥于這些細(xì)節(jié)更加難搞明白作用域鏈了促煮。上文也說道作用域鏈更像鏈表邮屁,個(gè)人也是這樣認(rèn)為,但兩書中都沒有明確地說是菠齿,權(quán)威指南倒是提了一下佑吝,而且作用域鏈也是很符合鏈表的特點(diǎn),如果不了解鏈表绳匀,但由不了解其他語言芋忿,推薦這本書《數(shù)據(jù)結(jié)構(gòu)與算法JavaScript描述》,吐槽完畢疾棵,作用域鏈的解析當(dāng)然沒有那么淺顯戈钢,想了解更多細(xì)節(jié)還是自己去看看書。

有說得不對(duì)的是尔,歡迎指出

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末殉了,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拟枚,更是在濱河造成了極大的恐慌压状,老刑警劉巖痛阻,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宗兼,死亡現(xiàn)場(chǎng)離奇詭異唁奢,居然都是意外死亡抱慌,警方通過查閱死者的電腦和手機(jī)推沸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門蔚携,熙熙樓的掌柜王于貴愁眉苦臉地迎上來房维,“玉大人傻粘,你說我怎么就攤上這事每窖。” “怎么了弦悉?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵窒典,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我稽莉,道長(zhǎng)瀑志,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任污秆,我火速辦了婚禮劈猪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘良拼。我一直安慰自己战得,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布庸推。 她就那樣靜靜地躺著常侦,像睡著了一般浇冰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上聋亡,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天肘习,我揣著相機(jī)與錄音,去河邊找鬼杀捻。 笑死井厌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的致讥。 我是一名探鬼主播仅仆,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼垢袱!你這毒婦竟也來了墓拜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤请契,失蹤者是張志新(化名)和其女友劉穎咳榜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體爽锥,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涌韩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了氯夷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臣樱。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖腮考,靈堂內(nèi)的尸體忽然破棺而出雇毫,到底是詐尸還是另有隱情,我是刑警寧澤踩蔚,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布棚放,位于F島的核電站,受9級(jí)特大地震影響馅闽,放射性物質(zhì)發(fā)生泄漏飘蚯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一捞蛋、第九天 我趴在偏房一處隱蔽的房頂上張望孝冒。 院中可真熱鬧,春花似錦拟杉、人聲如沸庄涡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽穴店。三九已至撕捍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泣洞,已是汗流浹背忧风。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留球凰,地道東北人狮腿。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像呕诉,于是被迫代替她去往敵國和親缘厢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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