函式進階內容 全域性物件
全域性物件
全域性物件提供可在任何地方使用的變數和函式。預設情況下,這些全域性變數內置於語言或環境中。
在瀏覽器中,它的名字是 “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
也就是說,一般不建議使用全域性變數。全域性變數應儘可能的少。與使用外部變數或全域性變數相比,函式獲取“輸入”變數併產生特定“輸出”的程式碼設計更加清晰,不易出錯且更易於測試。
使用 polyfills
我們使用全域性物件來測試對現代語言功能的支援。
例如,測試是否存在內建的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
。