Is window really global in Javascript?

Bart van Heukelom picture Bart van Heukelom · Jul 13, 2011 · Viewed 20.3k times · Source

Take this piece of Javascript in a browser:

<script>

console.log(window.someThing);
var x = 12;

function foo() {
   window.otherThing = x;
}

</script>

Inside foo we can access window, we all know that, but why exactly?

  • Is it some kind of special global variable?
  • Or does the "root scope" (inside the script tag) have it as an implicit local variable and is it simply "closure-inherited" as any other local variable (like x above) can be?

And how does that concur with variables declared directly inside the script tag being set as properties of window? (Or is that not so?)

<script>
var x = 12;
function() {
   console.log(window.x);
}
</script>

Answer

jAndy picture jAndy · Jul 13, 2011

The reason why you can access "out of scope" or "free" variables in ECMAscript is the such called Scope chain. The scope chain is a special property from each Execution context. As mentioned several times before, a context object looks at least like:

  • [[scope]]
  • Variable / Activation Object
  • "this" context value

each time you access a variable(-name) within a context (a function for instance), the lookup process always starts in it's own Activation Object. All formal parameters, function declarations and locally defined variables (var) are stored in that special object. If the variablename was not found in that object, the search goes into the [[Scope]]-chain. Each time a function(-context) is initialized, it'll copy all parent context variable/activation objects into its internal [[Scope]] property. That is what we call, a lexical scope. That is the reason why Closures work in ECMAscript. Since the Global context also has an Variable Object (more precisely, **the variable object for the global object is the global object itself) it also gets copied into the functions [[Scope]] property.

That is the reason why you can access window from within any function :-)

The above explanation has one important conceptional conclusion: Any function in ECMAscript is a Closure, which is true. Since every function will at least copy the global context VO in its [[Scope]] property.