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

为什么要在JavaScript中将全局变量添加到窗口对象?,javascript,Javascript,为什么要在JavaScript中将全局变量添加到窗口对象 var a = 1; console.log(window.a); ECMAScript 2015语言规范没有说明声明的变量或函数被添加到窗口全局对象。 但是,我想知道为什么声明为var的全局变量作为属性添加到窗口对象中 我好奇的是,它与ECMAScript语言规范无关 我使用了一个翻译器,所以请理解它是否奇怪。当变量被分配给某个变量时,如果不存在这样的标识符,则在规范中会注明: If IsUnresolvableReference(V

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

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

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


我使用了一个翻译器,所以请理解它是否奇怪。

当变量被分配给某个变量时,如果不存在这样的标识符,则在规范中会注明:

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).
在CreateGlobalBinding中,它被称为


全局对象可能是浏览器中的
窗口,或web worker中的
self
,等等。

我认为
var
导致向全局对象添加属性的原因(在您提供的示例中)与Javascript中的环境链接方式有关;它们通过外部参照链接,但全球环境没有外部参照。也许将它们作为属性绑定到全局对象的选择源于全局环境中缺少外部引用

全局范围是“最外层”范围—它没有外部范围。它的 环境就是全球环境。每个环境都是相互关联的 通过一系列 通过外部引用链接。全球经济的外部参照 环境为空


来源:

global
用于NodeJS(服务器端)。对于浏览器,
global
window
“ECMAScript 2015语言规范没有说明声明的变量或函数已添加到window全局对象。”[需要引文]由于这是ES1的一部分,我不确定为什么ES6将其删除。或者您是如何确定它不在规范中的。我相信问题在于为什么变量的作用域在
窗口中。这解释了为什么顶级变量被设置为
global
@choz“,这解释了为什么顶级变量被设置为global”???“让globalObj成为GetGlobalObject()”绝对不是说“global”。
GetGlobalObject
抽象操作返回全局对象,全局对象在浏览器环境中为
window
。所有这些答案都解释了为什么变量设置在
window
上。您如何知道它是
window
?对于网络工作者来说,它也可能是
self
。@choz因为OP询问的是
window
,我认为可以安全地假设问题的上下文是一个浏览器,其中全局对象是
window
。如果OP问的是网络工作者,我觉得他们不会提到
window
作为全局属性的添加对象。@VLAZ我实际上是指OP如何可能知道
GetGlobalObject
对于浏览器是指
window
,对于其他浏览器是指其他东西。但是,最后一次编辑应该可以回答这个问题。不,
var
s在全局上下文中声明,只是添加到全局对象中。这就是它的工作原理。有没有链接对这里的任何东西都没有影响。@VLAZ我的答案是唯一一个试图回答他问题的“为什么”方面的答案。我知道它是怎么工作的。问题是“为什么?”“为什么?”的答案是“因为规格说明如此”。如果规范说不应该将变量添加到全局对象,那么它们就不会被添加,例如再说一次,这并不是因为任何链接。@VLAZ想得更深:为什么编写规范的人决定这样做?这就是问题的实质。这家伙不是问规格如何,他是问他们为什么会这样。一个人或一群人有意识地决定这样做。是什么导致他们当时决定采用这种方式?不幸的是,“为什么规范是以这种方式编写的”并不是主题。主要是因为除了语言设计师参与并分享推理之外,它无法得到权威性的回答。或者其他任何使用资源来解释设计师推理的人。举个例子:你的答案不是这样的。我们所能做的就是猜测。也许当时的规格没有经过深思熟虑。JS是在几天内发展起来的,时至今日,Brendan Eich提到了许多这一事实。尽管如此,OP声称根据规范,
var
s不应该进入
window
,但这是错误的。
6. Let varDeclarations be the VarScopedDeclarations of script.
...
18. For each String vn of declaredVarNames, do
  a. Perform ? env.CreateGlobalVarBinding(vn, false).