问题
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 (likex
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>
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
It has to do with the scope chain.
Have a look at the following presentation of Nicholas C. Zakas. (starting around min 5)
回答5:
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)
回答6:
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;
回答7:
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...
来源:https://stackoverflow.com/questions/6679635/is-window-really-global-in-javascript