2022 年 7 月 1 日

全局对象

全局对象提供了在任何地方都可用的变量和函数。默认情况下,这些变量和函数是内置于语言或环境中的。

在浏览器中,它被命名为 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

教程地图

评论

在评论之前请阅读此内容…
  • 如果您有改进建议 - 请 提交 GitHub 问题 或提交拉取请求,而不是发表评论。
  • 如果您无法理解文章中的某些内容 – 请详细说明。
  • 要插入一些代码,请使用 <code> 标记,对于多行代码 – 将它们包装在 <pre> 标记中,对于超过 10 行的代码 – 使用沙箱 (plnkrjsbincodepen…)