1

Why are global variables added to a window object in JavaScript?

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

ECMAScript 2015 language specification does not say that declared var or function is added to window global objects. However, I would like to know why the global variable declared var is added as a property to the window object.

What I'm curious about is that it has nothing to do with ECMAScript language specification?

I used a translator, so please understand if it's weird.

BlueBear
  • 25
  • 6
  • 1
    `global` is for NodeJS (server-side). For browser, the `global` is `window`. – choz May 31 '21 at 16:38
  • "*ECMAScript 2015 language specification does not say that declared var or function is added to window global objects.*" [citation needed] Since this has been part of ES1, I'm not sure why you thing ES6 *removed* it. Or how you determined it's not in the spec. – VLAZ May 31 '21 at 17:07

2 Answers2

3

It actually is noted in the specification here, when a variable is assigned to when no such identifier exists:

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).

And here, in CreateGlobalVarBinding, which is called 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).

The global object may be the window in a browser, or self in a web worker, or the Node global, etc.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • 1
    I believe the question is about why the variable is scoped at `window`. And this explains why the top-level variable is set to `global`. – choz May 31 '21 at 16:46
  • @choz "*And this explains why the top-level variable is set to global*" ??? "Let globalObj be GetGlobalObject()." is most definitely not saying "global". The `GetGlobalObject` abstract operation returns the global object and the global object is `window` in browser environments. All this answer explains is why a variable is set on `window`. – VLAZ May 31 '21 at 17:19
  • 1
    How do you know it's `window`? It could also be `self` for web workers. – choz May 31 '21 at 17:21
  • @choz Since OP is asking about `window`, I think it's safe to assume the context of the question is a browser where the global object is `window`. If OP was asking about web workers, I feel they wouldn't have mentioned `window` as the thing where global properties are added to. – VLAZ May 31 '21 at 17:27
  • @VLAZ I was actually referring how OP could possibly know that `GetGlobalObject` refers to `window` for browser, or something else for others. However, the last edit should answer the question. – choz May 31 '21 at 17:57
-1

I think the reason why var causes properties to be added to the global object (in the example you provided) has to do with how environments are linked in Javascript; they are linked by outer references, yet the global environment has no outer reference. Perhaps the choice to bind them to the global object, as properties, stems from this lack of outer reference in the global environment.

The global scope is the “outermost” scope – it has no outer scope. Its environment is the global environment. Every environment is connected with the global environment via a chain of environments that are linked by outer references. The outer reference of the global environment is null.

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

Lonnie Best
  • 9,936
  • 10
  • 57
  • 97
  • No, `var`s declared in the global context just get added to the global object. That's explicitly how it works. Having links or not has no effect on anything here. – VLAZ May 31 '21 at 17:51
  • @VLAZ My answer is the only one that attempts to answer the "why" aspect of his question. I know how it works. The question is "why?" – Lonnie Best May 31 '21 at 17:54
  • The answer to "why?" is "because the specs say so". If specs said that variables shouldn't be added to the global object, they wouldn't be. [That's how `const` and `let` work](https://stackoverflow.com/questions/55030498/why-dont-const-and-let-statements-get-defined-on-the-window-object), for example. Again, not because any links. – VLAZ May 31 '21 at 17:57
  • @VLAZ Think deeper: Why did the people who wrote the spec decide to do it that way? That's the essence of the question. The guy isn't asking how the specs are, he is ask *why* they are that way. A person or a group of people consciously decided to make it that way. What caused them to do decide this way at that time? – Lonnie Best May 31 '21 at 18:13
  • Unfortunately "Why were the specifications written this way" is not on topic. Mostly because it *cannot* be authoritatively answered other than a language designer coming in and sharing the reasoning. Or anybody else using a resource that explains the designer's reasoning. Case in point: your answer does not do that. All we can do is guess. Maybe the spec was just not well thought out at the time. JS was famously developed in *days* and to this day Brendan Eich refers many to that fact. With that said, OP claimed that `var`s should not go to `window` according to the specs but that's false. – VLAZ May 31 '21 at 18:21