全局對象提供可在任何地方使用的變量和函數。默認情況下,這些全局變量內建于語言或環境中。
在浏覽器中,它的名字是 “window”,對 Node.js 而言,它的名字是 “global”,其它環境可能用的是別的名字。
最近,globalThis
被作爲全局對象的標准名稱加入到了 JavaScript 中,所有環境都應該支持該名稱。所有主流浏覽器都支持它。
假設我們的環境是浏覽器,我們將在這兒使用 “window”。如果妳的腳本可能會用來在其他環境中運行,則最好使用 globalThis
。
全局對象的所有屬性都可以被直接訪問:
alert("Hello"); // 等同于 window.alert("Hello");
在浏覽器中,使用 var
(而不是 let/const
!)聲明的全局函數和變量會成爲全局對象的屬性。
var gVar = 5; alert(window.gVar); // 5(成爲了全局對象的屬性)
函數聲明(特指在主代碼流中具有 function
關鍵字的語句,而不是函數表達式)也有這樣的效果。
請不要依賴它!這種行爲是出于兼容性而存在的。現代腳本使用 JavaScript modules 所以不會發生這種事情。
如果我們使用 let
,就不會發生這種情況:
let gLet = 5; alert(window.gLet); // undefined(不會成爲全局對象的屬性)
如果壹個值非常重要,以至于妳想使它在全局範圍內可用,那麽可以直接將其作爲屬性寫入:
// 將當前用戶信息全局化,以允許所有腳本訪問它 window.currentUser = { name: "John" }; // 代碼中的另壹個位置 alert(currentUser.name); // John // 或者,如果我們有壹個名爲 "currentUser" 的局部變量 // 從 window 顯式地獲取它(這是安全的!) alert(window.currentUser.name); // John
也就是說,壹般不建議使用全局變量。全局變量應盡可能的少。與使用外部變量或全局變量相比,函數獲取“輸入”變量並産生特定“輸出”的代碼設計更加清晰,不易出錯且更易于測試。
我們使用全局對象來測試對現代語言功能的支持。
例如,測試是否存在內建的 Promise
對象(在版本特別舊的浏覽器中不存在):
if (!window.Promise) { alert("Your browser is really old!"); }
如果沒有(例如,我們使用的是舊版浏覽器),那麽我們可以創建 “polyfills”:添加環境不支持但在現代標准中存在的功能。
if (!window.Promise) { window.Promise = ... // 定制實現現代語言功能 }
全局對象包含應該在任何位置都可見的變量。
其中包括 JavaScript 的內建方法,例如 “Array” 和環境特定(environment-specific)的值,例如 window.innerHeight
— 浏覽器中的窗口高度。
全局對象有壹個通用名稱 globalThis
。
……但是更常見的是使用“老式”的環境特定(environment-specific)的名字,例如 window
(浏覽器)和 global
(Node.js)。
僅當值對于我們的項目而言確實是全局的時候,才應將其存儲在全局對象中。並保持其數量最少。
在浏覽器中,除非我們使用 modules,否則使用 var
聲明的全局函數和變量會成爲全局對象的屬性。
爲了使我們的代碼面向未來並更易于理解,我們應該使用直接的方式訪問全局對象的屬性,如 window.x
。