In JavaScript, there’s a global variable depending on the environment. In the browser, there’s the window
object. The worker context has the self
object as the global object. Node.js has the global
object.
In this article, we’ll look at the global object, what it does, and how and when to use it.
Scope of the Global Object
The global object is always in the topmost scope. There’s nothing else above it. Therefore, it can be accessed by anything. Consider the name, this makes sense.
In JavaScript, scopes don’t change at runtime, so we can get the scope of something from their location in the code.
Since the global object is in the topmost scope, it can be accessed by anything. For example, we can console.log
the window
object from anywhere and we can get the value for it.
The Global Object
A global object is an object where the properties of it are global variables. It’s called the window
object in browsers, self
in web workers, and global
in Node.js
There’s also a proposal to have a globalThis
global object that’s available in all contexts.
The global object contains all built-in global variables.
Creating Global Variables
We can create global variables by creating a property of the global object. In the browser context, this means that we create it as a property of the window
object.
There’re a few ways to do this. One way is to define as a property of the window
object as follows:
window.foo = 1;
Then we can reference as foo
or window.foo
anywhere in our code.
Another way is to use the var
keyword in the top level of our code. That is, it’s not nested in any block. We can define it as follows:
var foo = 1;
Getting or Setting Variables
We can get and set global variables just like how we declared it. For example, if we declared:
window.foo = 1;
Then we can reference window.foo
and assign values to them. If it’s declared with var
at the top level as in:
var foo = 1;
Then we can either write:
foo = 1;
or:
window.foo = 1;
Module
Each module has its own environment that isn’t exposed to the outside unless something is explicitly exported. However, we can still access global variables from there like in any other environment.
Caveats
The global object is considered a mistake. It’s easy to create global variables that clash with the names of other variables.
Also, we can easily change existing built-in global variables or ones that are defined by us. This is a problem which is avoided by using newer constructs like let
and const
to declare variables and constants and also using modules to protect private data and namespace them so that we can’t modify anything accidentally.
It was only created to make simple scripting on the browser easy. Now that we’re building full-fledged apps with JavaScript, using the global object too much will create lots of problems like we described before.
However, the global object in the browser environment has lots of properties that we can use to add features to our apps like window.SubtleCrypto
for cryptography, customElements
variable to declare Web Components and many more properties. location
is also a property of the window
object.
Likewise Node.js’ global
object has properties like __dirname
and __filename
, which is handy for accessing data about our current code. The console
object is useful for debugging, and Process
is useful for getting data about the currently running process.
setTimeout
, setInterval
are also part of the Node.js global
object.
The full list of properties is at Mozilla Developer Network.
It was also used to access variables from external scripts before JavaScript has modules. But now that we have modules, we definitely don’t need to use the global object for that purpose.
Also, testing is a lot harder since global variables are changed by everything. So, it’s hard to reason what’s going on with them.
Conclusion
Nowadays, we just use global variables like the window
object mostly for their built-in properties.
In our own code, we use what’s provided by the global object, but there isn’t any good use case to add any properties to the global object. It’s messy and hard to trace issues since everything modifies the global variable since everything can access it.
The better way is to modularize everything and then make expose the things that we need by exporting them.
However, the window
object does have lots of useful properties that we can use. This is the same for Node.js’ global
object.