Difference of Global and Window objects - javascript

What is the difference between the JavaScript Global object and Window object. I know in both, you don't have to declare the object to use the methods.

The window object encapsulates the global scope. Omitting var (or let) when declaring a variable will implicitly add that as a property to the global scope. It's unique in that sense since there is no equivalent to window when inside a different scope.
I'm going to quote myself on this one:
MDN's description of var states that the global scope is bound to the global object. This would suggest that declaring a variable (either with var at the top level, or without var inside a function) simply adds a new property to window (or an equivalent outside of the browser).
Try it out. Create a variable without using var, then look at the window object in your console. You'll see it in there. It's the equivalent of doing this:
Object.defineProperty(window, 'foo', {
value: "bar",
enumerable: true // see #dandavis' comment on iterating over implicit global vars
)}
This doesn't explain why that's the case. Just that window is unique in that everything is defined within it.

I could be wrong, but it seems to me that the so-called globals are defined under the window object.

In JavaScript that is running in a browser, window is at the top of the scope chain. If you define a "global" variable, it is implied that it is under the window object.
For example:
// Global variable
var g = 0;
function foo(){
window.g = 1
// This will output '1'
alert(g);
}

Related

A Few Questions About the Global Object

A global object is an object that always exists in the global scope. In JavaScript there is always a global object defined.
Can there be more than one global object? Why do people say Window is a global object when MDN doesnt say this?
Every browser window has a single top level Window object routinely referred to as global object. The global object is accessible via window variable.
The object exposes a number of properties, most importantly document which is also an object, methods, and events.
A developer may define (via script) variables (var) and functions which automatically become properties and methods of window (global) object (provided they are declared on top (global) level).
For example, an expression var a = 1; declares a variable named a (and assign numeric value to it). This variable is accessible by its name (a) and as well as window.a and window['a'].
The reference to the global window object can be omitted so window.a = 2; and a = 2; are equivalent (but not ['a'] = 2; which is syntax error).
Also note that global window object belongs to the browser window, not to javascript. The browser only expose it to Scripting Engine.
This is javascript basics.
I hope this explanation clears a little your confusion.

Why can't I use certain variable names in javascript?

While coding I realized that certain variable names such as top, self, left\right create all sorts of errors when you try to use them. What's the reason behind this in JavaScript, while other languages can use them?
You can't use them as global variables because there already exist global accessor properties with these names.
top is used to access the top frame.
self is used to access the global object.
As far as I know there is no problem with left and right.
console.log(Object.getOwnPropertyDescriptor(window, 'top'));
console.log(Object.getOwnPropertyDescriptor(window, 'self'));
Attempting to assign some value to these variables will run the setter, which may not do what you expected. If there is only a getter but no setter, the assignment will be ignored in sloppy mode and throw in strict mode.
There is no problem in using these names as local variables. You should not use global variables anyways.
(function() {
var top = 123; // local variable
console.log(top === 123); // true - no problem
})();
var top = 456; // global variable
console.log(top === 456); // false !!!
There are no problems using variables with those names in JavaScript in most cases.
In some environments, some of the names are already used for existing global variables and are read only.
top is one such example, it refers to the top level frame.
You can still use it as the name of a variable in a non-global context.
Most probably you use variables without declaring them with var/let, and in such circumstances, you modify properties of the global execution environment.
In browser, the global execution environment is window, so when you do
self = '...'
you effectively do
window.self = '...'
self, top, left, right are properties of window object which may have certain non-standard behaviors. Many built-in properties of window object are in fact implicit setters which do more than setting a variable - they can also modify the current page, navigate etc. Also, many built-in properties of window can not be overridden, so assigning to them has no effect.
Contrary, when you do
(function() {
var self = '...'
})()
you should not have any problems.
You need a function call to make it work properly, to create a new scope, because in global scope, even with var, you'd still implicitly assign a property to window.

Declaring Empty Variables to make them global

In a JavaScript environment can I declare a variable before a function to make the variable reachable on a global level.
For instance:
var a;
function something(){
a = Math.random()
}
Will this make "a" a global variable?
or is using...
var a = function(){
var b = Math.random();
return b;
}
document.write(a())
Really the only way to do it?
Is there a way to make "b" global other than calling the function "a()"?
There are basically 3 ways to declare a global variable:
Declaring it in the global scope, outside of any function scope.
Explicitly assigning it as a property of the window object: window.a = 'foo'.
Not declaring it at all (not recommended). If you omit the var keyword when you first use the variable, it'll be declared globally no matter where in your code that happens.
Note #1: When in strict mode, you'll get an error if you don't declare your variable (as in #3 above).
Note #2: Using the window object to assign a global variable (as in #2 above) works fine in a browser environment, but might not work in other implementations (such as nodejs), since the global scope there is not a window object. If you're using a different environment and want to explicitly assign your global variables, you'll have to be aware of what the global object is called.
Will this make "a" a global variable?
A var declaration makes the variable local to the enclosing scope, which is usually a function one's. If you are executing your code in global scope, then a will be a global variable. You could as well just omit the var, then your variable would be implicitly global (though explicit declaration is better to show your intention).
Is there a way to make "b" global other than calling the function "a()"?
Your b variable is always local to the function a and will never leave it, unless you remove the var.
Before you think of making a variable global scope, you should consider JavaScript global namespace pollution. The more global variables you declare, the more it is likely that you application will get into conflict with another application's namespace and break. As such, it is highly important minimize the number of global variables.

Is 'window' really global in JavaScript?

Take this piece of JavaScript code 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>
The reason why you can access "out of scope" or "free" variables in ECMAScript is the so-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 its 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.
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.
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 specification.
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.
It has to do with the scope chain.
Have a look at the presentation of Nicholas C. Zakas (starting around 5 minutes).
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),
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;
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...

Is 'window' always on top of the scope chain in javascript?

I've seen global variables defined with window.global_name.
I wonder why not just using global_name even if this script will be run in closure.
UPD: seems like IE doesn't explicitly add it to the window object, when you declare it inside of a closure
The last object on the scope chain in any ECMAScript environment is always the global object. In browsers, window is to all intents and purposes the global object. If you want to access a property of the global object x or a global variable x (which are almost but not quite the same thing), you should explicitly qualify it with window.x to avoid the possibility of x being resolved as a property of another object on the scope chain, or globalObj.x if you care about portability to non-browser environments. You can get a reference to the global object from anywhere in ECMAScript 3 or non-strict ECMAScript 5 as follows:
var globalObj = (function() { return this; })();
window.x is safer than simply x if there might possibly be another x in the current or preceding scopes. That being said, even window isn't fool-proof because you could define a variable named window.
They have similar effects, but window lets you explicitly declare that you're deliberately using a global. Otherwise, the reader doesn't know whether it's a var further up the scope chain, you just forgot to declare it, etc.
Unless you introduce another scope, e.g. by wrapping your code in a function, window === this === <the global scope>
However, window and this have the advantage that you can use the array syntax (window['something']) so you can access globals even if you have their name only in a string without using evil things like eval.
The answer is yes. If you declare a variable without the var keyword (inside a function), the variable will become implicitely a member of the window object, that is automatically initialized by the browser.
Outside a function, with or without the var keyword, the variable becomes implicitely a member of the window object.

Categories

Resources