为啥在 JavaScript 中将全局变量添加到窗口对象?

Posted

技术标签:

【中文标题】为啥在 JavaScript 中将全局变量添加到窗口对象?【英文标题】:Why are global variables added to a window object in JavaScript?为什么在 JavaScript 中将全局变量添加到窗口对象? 【发布时间】:2021-08-18 23:31:45 【问题描述】:

为什么在 javascript 中将全局变量添加到窗口对象中?

var a = 1;
console.log(window.a);

ECMAScript 2015 语言规范没有说声明的 var 或函数被添加到窗口全局对象中。 但是,我想知道为什么将声明为 var 的全局变量作为属性添加到 window 对象中。

我很好奇的是它与 ECMAScript 语言规范无关?

我使用了翻译器,所以如果很奇怪,请理解。

【问题讨论】:

global 用于 NodeJS(服务器端)。对于浏览器,globalwindow "ECMAScript 2015 语言规范没有说声明的 var 或函数被添加到窗口全局对象中。" [需要引用] 因为这是 ES1 的一部分,所以我'我不知道为什么你的东西 ES6 removed 它。或者您如何确定它不在规范中。 【参考方案1】:

实际上在规范here 中指出,当不存在这样的标识符时将变量分配给:

If IsUnresolvableReference(V) is true, then
  a. If V.[[Strict]] is true, throw a ReferenceError 
exception.
  b. Let globalObj be GetGlobalObject().
  c. Return ? Set(globalObj, V.[[ReferencedName]], W, false).

还有here,在CreateGlobalVarBinding中,叫做when a variable is declared at the top level of a script。

6. Let varDeclarations be the VarScopedDeclarations of script.
...
18. For each String vn of declaredVarNames, do
  a. Perform ? env.CreateGlobalVarBinding(vn, false).

全局对象可以是浏览器中的window,或者web worker中的self,或者the Node global等。

【讨论】:

我相信问题在于为什么变量的范围是window。这就解释了为什么***变量设置为global @choz "这就解释了为什么***变量设置为全局" ??? “让 globalObj 成为 GetGlobalObject()。”绝对不是说“全球”。 GetGlobalObject抽象操作返回全局对象,在浏览器环境中全局对象为window。所有这些答案都解释了为什么在window 上设置了一个变量。 你怎么知道是window?对于网络工作者,也可以是 self @choz 由于 OP 询问window,我认为可以安全地假设问题的上下文是全局对象为window 的浏览器。如果 OP 询问网络工作者,我觉得他们不会提到 window 作为添加全局属性的东西。 @VLAZ 我实际上指的是 OP 怎么可能知道 GetGlobalObject 指的是浏览器的 window,或者其他的东西。但是,最后的编辑应该回答了这个问题。【参考方案2】:

我认为var 导致属性被添加到全局对象(在您提供的示例中)的原因与 JavaScript 中的环境如何linked 有关;它们由外部引用链接,但全局环境没有外部引用。也许将它们作为属性绑定到全局对象的选择源于全局环境中缺乏外部引用。

全局作用域是“最外层”作用域——它没有外部作用域。它的 环境是全球环境。每个环境都是相互关联的 通过一系列环境与全局环境 由外部引用链接。全局的外部参考 环境是null

来源:https://2ality.com/2019/07/global-scope.html#the-global-object

【讨论】:

不,在全局上下文中声明的vars 只是被添加到全局对象中。这就是它的工作原理。有没有链接对这里的任何东西都没有影响。 @VLAZ 我的答案是唯一一个试图回答他问题的“为什么”方面的答案。我知道它是如何工作的。问题是“为什么?” “为什么?”的答案是“因为规格是这样说的”。如果规范说不应该将变量添加到全局对象中,那么它们就不会添加。 That's how const and let work,例如。同样,不是因为任何链接。 @VLAZ 深入思考:为什么编写规范的人决定这样做?这就是问题的本质。这家伙不是在问规格如何,而是在问为什么它们是这样的。一个人或一群人有意识地决定这样做。是什么让他们当时做出了这样的决定? 不幸的是,“为什么以这种方式编写规范”不是主题。主要是因为它无法得到权威的回答,除了语言设计者进来并分享推理。或者其他任何人使用解释设计师推理的资源。举个例子:你的答案没有做到这一点。我们能做的就是猜测。也许当时的规范没有经过深思熟虑。 JS 是在 几天 中开发出来的,直到今天,Brendan Eich 提到很多人都提到了这一事实。话虽如此,OP 声称根据规范,vars 不应转到window,但这是错误的。

以上是关于为啥在 JavaScript 中将全局变量添加到窗口对象?的主要内容,如果未能解决你的问题,请参考以下文章

在Javascript中将多个变量分配给相同的值?

为啥我需要在 JavaScript 中将 unix 时间戳乘以 1000?

在Javascript中将多个变量分配给相同的值

为啥全局变量不添加到浏览器的窗口对象? [复制]

在 JavaScript(特别是 NativeScript)中添加全局变量/函数

在 Browserify 中将模块公开为全局变量