原文: 2ality.com/2019/07/glo…javascript
翻譯: 劉小夕html
在這篇博文中,咱們將研究 JavaScript
的全局變量是如何工做的。如:scripts
的範圍,所謂的全局對象等等。java
更多文章可戳: github.com/YvetteLau/B…git
變量的詞法做用域(簡稱:做用域)是能夠訪問它的程序的區域。JavaScript
的做用域是靜態的(它們在運行時不會改變)而且它們能夠嵌套 - 例如:github
function func() { // (A)
const foo = 1;
if (true) { // (B)
const bar = 2;
}
}
複製代碼
if
語句引入的做用域(行B)嵌套在函數 func()
(行A)的做用域內。瀏覽器
在示例中,func
是 if
的外層做用域。數據結構
在 JavaScript
語言規範中,做用域是經過詞法做用域「實現」的。它們由兩部分組成:函數
JavaScript
存儲變量的地方。環境記錄中的一個 key-value
條目稱爲綁定。所以,嵌套做用域樹能夠由嵌套環境樹表示。this
全局對象是一個對象,其屬性是全局變量。spa
this
Node.js
和 Web Workers
中。Web Workers
。 可是 Node.js
不支持它。Node.js
中可用。全局對象包含全部內置全局變量。
全局做用域是「最外層」做用域 - 它沒有外部做用域。它的環境是全局環境。每一個環境都經過由外部引用連接的一系列環境與全局環境相關聯。 全局環境的外部引用爲 null
。
全局環境結合了兩個環境記錄:
下圖顯示了這些數據結構。
接下來的兩個小節將解釋如何組合對象記錄和聲明式記錄。
爲了建立一個真正全局的變量,你必須處於全局做用域內 - 必需要在 scripts
的頂層:
const
,let
和 class
在聲明式環境記錄中建立綁定。var
和函數聲明在對象式環境記錄中建立綁定。<script>
const one = 1;
var two = 2;
</script>
<script>
// All scripts share the same top-level scope:
console.log(one); // 1
console.log(two); // 2
// Not all declarations create properties of the global object:
console.log(window.one); // undefined
console.log(window.two); // 2
</script>
複製代碼
此外,全局對象包含全部內置全局變量,並經過對象式記錄將它們給全局環境。
當咱們獲取或設置變量而且兩個環境記錄都具備該變量的綁定時,聲明式環境記錄將獲勝:
<script>
let foo = 1; // 聲明式環境記錄
globalThis.foo = 2; // 對象式環境記錄
console.log(foo); // 1 (聲明式記錄獲勝)
console.log(globalThis.foo); // 2
</script>
複製代碼
每一個模塊都有本身的環境,它存儲全部頂級聲明 - 包括導入。模塊環境的外部環境是全局環境。
一般認爲全局對象是錯誤的。所以,較新的構造(如 const
,let
和 classes
)會建立正常的全局變量,不會成爲全局對象的屬性。(在script
做用域內時)。
值得慶幸的是,大多數用現代 JavaScript
編寫的代碼都存在於 ECMAScript
模塊和CommonJS
模塊中。每一個模塊都有本身的做用域,這就是爲何管理全局變量的規則不多對基於模塊的代碼很重要。
最後謝謝各位小夥伴願意花費寶貴的時間閱讀本文,若是本文給了您一點幫助或者是啓發,請不要吝嗇你的贊和Star,您的確定是我前進的最大動力。github.com/YvetteLau/B…