JavaScript的全局變量是如何工作的

在這篇博客文章中喇聊,我們將研究JavaScript的全局變量是如何工作的恍风。一些有趣的現(xiàn)象是: 腳本的作用域、所謂的全局對象 等等誓篱。

作用域

變量的詞法作用域(lexical scope)(簡稱:作用域(scope))是程序中可以訪問它的區(qū)域朋贬。JavaScript的作用域是靜態(tài)的(它們在運行時不會改變)并且它們可以嵌套 - 例如:

function func() { // (A)
  const foo = 1;
  if (true) { // (B)
    const bar = 2;
  }
}

if語句(B行)引入的作用域嵌套在函數(shù)func()(A行)的作用域內(nèi)。

在這里例子里窜骄,func就是if的外部作用域锦募。

詞法環(huán)境

在JavaScript的語言規(guī)范中,作用域是通過詞法環(huán)境來"實現(xiàn)"的邻遏。它們由兩部分組成:

  • 將變量名映射到變量值的環(huán)境記錄(聯(lián)想字典)糠亩。這是JavaScript存儲變量的地方。環(huán)境記錄的鍵值對入口被叫做綁定(binding)准验。
  • 外部環(huán)境的引用——表示當前環(huán)境所代表作用域的外部作用域的環(huán)境赎线。

因此,嵌套作用域樹由一個嵌套環(huán)境樹表示糊饱,該樹由外部引用鏈接垂寥。

全局對象

全局對象是一個對象,他的屬性是全局變量。等下就會介紹他是怎么去和環(huán)境樹相適應滞项。它們有幾個不同的名稱:

  • 任意地方(提案功能): globalThis
  • 全局對象的其他名稱取決于平臺和語言結構:
    • window:是引用全局對象的經(jīng)典方式狭归。但它只在普通瀏覽器代碼中工作;不存在Node.js中,也不存在Web Workers中(與普通瀏覽器代碼并發(fā)運行的進程)文判。
    • self:瀏覽器的任何地方都是可用的唉铜,包括Web Workers。但是Node.js中不支持律杠。
    • global:只在Node.js中被支持潭流。

全局對象包含所有內(nèi)置的全局變量。

全局環(huán)境

全局作用域是“最外層的”作用域——它沒有外部作用域柜去。它的環(huán)境是全局環(huán)境灰嫉。每個環(huán)境都通過由外部引用鏈接的環(huán)境鏈與全局環(huán)境聯(lián)系。全局環(huán)境的外部引用是null嗓奢。

全局環(huán)境結合了兩個環(huán)境記錄:

  • 一個對象環(huán)境記錄 的作用就像一個普通的環(huán)境記錄讼撒,但會保持他的綁定和對象同步。在這種情況下股耽,對象是全局對象根盒。
  • 一個普通的(聲明性的)環(huán)境記錄。

下圖顯示了這些數(shù)據(jù)結構物蝙。過一會就會解釋腳本作用域模塊環(huán)境炎滞。

image.png

接下來的兩個小節(jié)將解釋對象記錄和聲明性記錄是如何組合的。

創(chuàng)建變量

為了創(chuàng)建一個真正意義上的全局變量诬乞,你必須在全局作用域中 -- 只有一種情況册赛,那就是在腳本的頂級。

  • 頂級const震嫉,letclass在聲明性記錄中創(chuàng)建綁定森瘪。
  • 頂級varfunction聲明在對象記錄中創(chuàng)建綁定。
<script>
  const one = 1;
  var two = 2;
</script>
<script>
  // 所有腳本共享相同的頂級作用域:
  console.log(one); // 1
  console.log(two); // 2
  
  // 并非所有聲明都創(chuàng)建全局對象的屬性:
  console.log(window.one); // undefined
  console.log(window.two); // 2
</script>

此外票堵,全局對象包含所有內(nèi)置的全局變量扼睬,并通過對象記錄將它們貢獻給全局環(huán)境。

獲取或設置變量

當我們獲取或者設置一個變量悴势,并且兩個的環(huán)境記錄(對象記錄和聲明記錄)都有對變量的綁定窗宇,然后聲明性記錄會具有優(yōu)勢:

<script>
  let foo = 1; // 聲明性的環(huán)境記錄
  globalThis.foo = 2; // 對象環(huán)境記錄

  console.log(foo); // 1 (聲明性的環(huán)境記錄具有優(yōu)勢)
  console.log(globalThis.foo); // 2
</script>

模塊環(huán)境

每個模塊有屬于他自己的環(huán)境。他存儲所有的頂級聲明瞳浦,也包含導入(import)担映。模塊環(huán)境的外部環(huán)境是全局環(huán)境。

為什么JavaScript既有正常的全局變量又有全局對象叫潦?

全局對象通常會被認為是一個錯誤蝇完。因此,較新的構造(如const、let和class)創(chuàng)建正常的全局變量(在腳本作用域中)短蜕。

值得慶幸的是氢架,大多數(shù)用現(xiàn)代JavaScript編寫的代碼都存在于ECMAScript模塊和CommonJS模塊中。每個模塊都有自己的作用域朋魔,這就是為什么控制全局變量的規(guī)則很少對基于模塊的代碼有影響岖研。

進一步閱讀

總結

譯者個人總結

環(huán)境記錄包含了對象環(huán)境記錄(object record)和聲明性環(huán)境記錄(declarative record)孙援。

let,const, class的這些聲明都是在聲明性記錄(declarative record)中創(chuàng)建的綁定,

var,function這種聲明都是在對象記錄(object record)中創(chuàng)建的綁定。

全局對象之所以可以訪問var這些聲明扇雕,是因為他會通過對象記錄來獲取拓售。

對于js來說,全局對象通常被認為是一個錯誤镶奉,所以新的聲明方法都是存儲在聲明性記錄里础淤。

原文: JavaScript的全局變量是如何工作的?

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哨苛,隨后出現(xiàn)的幾起案子鸽凶,更是在濱河造成了極大的恐慌,老刑警劉巖建峭,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玻侥,死亡現(xiàn)場離奇詭異,居然都是意外死亡迹缀,警方通過查閱死者的電腦和手機使碾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祝懂,“玉大人,你說我怎么就攤上這事拘鞋⊙馀睿” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵盆色,是天一觀的道長灰蛙。 經(jīng)常有香客問我,道長隔躲,這世上最難降的妖魔是什么摩梧? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮宣旱,結果婚禮上仅父,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好笙纤,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布耗溜。 她就那樣靜靜地躺著,像睡著了一般省容。 火紅的嫁衣襯著肌膚如雪抖拴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天腥椒,我揣著相機與錄音阿宅,去河邊找鬼。 笑死笼蛛,一個胖子當著我的面吹牛家夺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播伐弹,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼拉馋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惨好?” 一聲冷哼從身側響起煌茴,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎日川,沒想到半個月后蔓腐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡龄句,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年回论,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片分歇。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡傀蓉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出职抡,到底是詐尸還是另有隱情葬燎,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布缚甩,位于F島的核電站谱净,受9級特大地震影響,放射性物質發(fā)生泄漏擅威。R本人自食惡果不足惜壕探,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一企垦、第九天 我趴在偏房一處隱蔽的房頂上張望起宽。 院中可真熱鬧与柑,春花似錦、人聲如沸辛友。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽比驻。三九已至,卻和暖如春认轨,著一層夾襖步出監(jiān)牢的瞬間绅络,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工嘁字, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留恩急,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓纪蜒,卻偏偏與公主長得像衷恭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子纯续,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

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