全域物件提供隨時可用的變數和函式。預設情況下,這些物件是內建於語言或環境中。
在瀏覽器中,它被命名為 window
,在 Node.js 中,它被命名為 global
,在其他環境中,它可能有不同的名稱。
最近,globalThis
已新增至語言中,作為全域物件的標準化名稱,應支援所有環境。它在所有主流瀏覽器中都受支援。
我們將在此處使用 window
,假設我們的環境是瀏覽器。如果你的指令碼可能在其他環境中執行,最好改用 globalThis
。
所有全域物件的屬性都可以直接存取
alert("Hello");
// is the same as
window.alert("Hello");
在瀏覽器中,使用 var
(不是 let/const
!)宣告的全域函式和變數會變成全域物件的屬性
var gVar = 5;
alert(window.gVar); // 5 (became a property of the global object)
函式宣告也有相同的效果(主程式碼流程中使用 function
關鍵字的陳述式,不是函式表達式)。
請不要依賴這個!這種行為是為了相容性而存在的。現代腳本使用 JavaScript 模組,在模組中不會發生這種事。
如果我們改用 let
,這種事就不會發生
let gLet = 5;
alert(window.gLet); // undefined (doesn't become a property of the global object)
如果某個值非常重要,你希望讓它在全域中可用,請直接將它寫成屬性
// make current user information global, to let all scripts access it
window.currentUser = {
name: "John"
};
// somewhere else in code
alert(currentUser.name); // John
// or, if we have a local variable with the name "currentUser"
// get it from window explicitly (safe!)
alert(window.currentUser.name); // John
話雖如此,一般不建議使用全域變數。全域變數應該盡量少。函式取得「輸入」變數並產生特定「結果」的程式碼設計比較清楚,比較不容易出錯,也比使用外部或全域變數更容易測試。
用於多重填充
我們使用全域物件來測試對現代語言功能的支援。
例如,測試內建 Promise
物件是否存在(在非常舊的瀏覽器中不存在)
if (!window.Promise) {
alert("Your browser is really old!");
}
如果沒有(例如,我們在舊瀏覽器中),我們可以建立「多重填充」:加入環境不支援,但存在於現代標準中的函式。
if (!window.Promise) {
window.Promise = ... // custom implementation of the modern language feature
}
摘要
-
全域物件包含應該在所有地方都可用的變數。
這包括 JavaScript 內建函式,例如
Array
和環境特定的值,例如window.innerHeight
,也就是瀏覽器中的視窗高度。 -
全域物件有一個通用名稱
globalThis
。…但更常使用「舊式」環境特定的名稱來指稱它,例如
window
(瀏覽器)和global
(Node.js)。 -
我們應該只在它們對我們的專案真的是全域時,才將值儲存在全域物件中。而且要將它們的數量減到最低。
-
在瀏覽器中,除非我們使用 模組,否則使用
var
宣告的全域函式和變數會變成全域物件的屬性。 -
為了讓我們的程式碼更具備未來性,也更容易理解,我們應該直接存取全域物件的屬性,例如
window.x
。
留言
<code>
標籤,對於多行程式碼 – 將它們包覆在<pre>
標籤中,對於超過 10 行程式碼 – 使用 sandbox (plnkr、jsbin、codepen…)