By Bart van Heukelom


2011-07-13 13:24:55 8 Comments

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>

7 comments

@Wilt 2016-06-02 12:42:29

The window global scope applies only to the main thread. In web workers there is no window global variable. Instead you have WorkerGlobalScope inside a WebWorker and in a SharedWorkerGlobalScope inside a SharedWorker.

This worker global scope is stored in a variable called self and as MDN describes it:

this scope contains the information usually conveyed by Window objects.

This can become a problem when 3rd party code you are using in your web worker is using the window object. This can be easily solved by declaring a window variable as suggested by @FelipeMicaroniLalli in his answer here like this:

var window = self;

@Saxoier 2011-07-13 13:40:36

It has to do with the scope chain.

Have a look at the following presentation of Nicholas C. Zakas. (starting around min 5)

@Bart van Heukelom 2011-07-13 13:58:14

Interesting. Looks like the global scope is indeed just a regular one, just at the highest level.

@user113716 2011-07-13 13:52:20

It's all defined in ECMAScript.

The global is a Lexical environment that doesn't have an outer lexical environment. All other environments are nested within it, and is bound to a global object with properties specified by the spec.

This places the properties of the global object at the start of the scope chain, from which all other environments inherit.

ES 10.2.3 The Global Environment:

The global environment is a unique Lexical Environment which is created before any ECMAScript code is executed. The global environment’s Environment Record is an object environment record whose binding object is the global object (15.1). The global environment’s outer environment reference is null.

As ECMAScript code is executed, additional properties may be added to the global object and the initial properties may be modified.

ES 15.1 The Global Object

The unique global object is created before control enters any execution context.

Unless otherwise specified, the standard built-in properties of the global object have attributes {[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.

The global object does not have a [[Construct]] internal property; it is not possible to use the global object as a constructor with the new operator.

The global object does not have a [[Call]] internal property; it is not possible to invoke the global object as a function.

The values of the [[Prototype]] and [[Class]] internal properties of the global object are implementation-dependent.

In addition to the properties defined in this specification the global object may have additional host defined properties. This may include a property whose value is the global object itself; for example, in the HTML document object model the window property of the global object is the global object itself.

@katspaugh 2011-07-13 14:18:54

Come to think of it, window.window.window.window.window === window.window.window.window.

@Shaz 2011-07-27 12:50:19

When does the compiler know when to stop so that we don't have infinite window.window.window etc...?

@user113716 2011-07-27 13:14:15

@Shaz: It is a circular reference, so it doesn't end. The compiler only creates one reference. It just happens to be a reference back to the original object on which the reference was created. That's why you can do window.window.window... Like this: var obj = {}; obj.obj = obj;. There's only one reference created but it's a reference back to the original, so you can do obj.obj.obj.obj.obj.obj.obj === obj.

@Vithozor 2011-07-13 13:49:39

In the book Javascript: The Good Parts, as I understand, Douglas Crockford explains that window is the global object of the web browser that contains all the global variables. It is like the One Ring...

@daveoncode 2011-07-13 13:57:36

window is the base scope of all javascript objects, and it's automatically "attached" to each variables you define, unless you use "var" before the declaration, in this case the scope of the variable it's local (that means that it's contained inside the parent function, or is otherwise global too, if you are declaring your variable outside a function block). Moreover window is defined as a constant, that is you can't redefine the window object (you will get an error saying "type error: redeclaration of const window").

so:

window.foo = 5;

it's the same as:

var foo = 5;

or:

function() {
foo = 5;
}

but:

function() {
var foo = 5;
}

in this case "foo" is local (window.foo === undefined)

@katspaugh 2011-07-13 14:23:44

You can redefine window. (function (window) { alert(window) })(1).

@daveoncode 2011-07-13 14:32:56

you are not redefining window in this way, you are creating a closure with an argument with name "window"... it's a different thing! :)

@overexchange 2017-09-07 15:49:18

function syntax is invalid, requires a name. variable foo=2 in function f(){} is not equivalent to window.foo

@jAndy 2011-07-13 13:50:07

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.

@pseudosavant 2013-06-12 22:19:59

Is there a way to alter the scope chain? E.g. to prevent a function from having access to the global scope?

@overexchange 2017-09-07 15:51:05

How to access [[Scope]] property syntactically?

@Quentin 2011-07-13 13:27:30

Is window really global in Javascript?

Yes. Unless you create a new variable called window in a narrower scope

function foo() {
    var window;
}

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

Any function can access variables declared in a wider scope. There is nothing special about window there.

@Bart van Heukelom 2011-07-13 13:29:12

But is the scope in which window lives simply the widest scope in the scope chain, or is it a special global scope? How is it resolved internally at runtime by the Javascript engine?

@Quentin 2011-07-13 13:30:21

As I said "nothing special" (well, that isn't quite true, since it is the default variable, but nothing special with regards to scope anyway).

@Shef 2011-07-13 13:39:14

@Bart van Heukelom: It will check if there is a variable with the same name on the local scope, if none found, it will go upwards until Object.

@Bart van Heukelom 2011-07-13 13:47:50

@Shef Until Object? Surely window is not a static property of Object...or is it?

@Shef 2011-07-13 13:53:03

@Bart van Heukelom: Sorry, meant to write Window object.

Related Questions

Sponsored Content

89 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6168524 View
  • 7693 Score
  • 89 Answer
  • Tags:   javascript arrays

86 Answered Questions

[SOLVED] How do JavaScript closures work?

27 Answered Questions

[SOLVED] What does "use strict" do in JavaScript, and what is the reasoning behind it?

41 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

58 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

3 Answered Questions

33 Answered Questions

[SOLVED] For-each over an array in JavaScript?

44 Answered Questions

[SOLVED] JavaScript closure inside loops – simple practical example

18 Answered Questions

[SOLVED] Using global variables in a function

Sponsored Content