JavaScript Under The Hood Pt. 1: The Global Object

As many of us know, the behaviors that JavaScript exhibits can sometimes be a bit, ahem, weird. A while ago I was watching a short comical video by Gary Bernhardt on certain wacky behaviors of Ruby and Javascript (Skip to 1:20 for JavaScript) that exposes some of these behaviors in a funny way.
While this video is hilarious, it’s worth noting that many of these strange behaviors can actually be understood with a deep understanding of how the JavaScript engine works behind the scenes. And, more importantly than allowing you to demystify video memes, this understanding will allow you to solve certain bugs that the rest of your team might find strange or hard to track down. This is one of the most common knocks on JavaScript. Its’ sometimes strange and unexpected behavior.
What most programmers don’t realize is that, while JavaScript may look similar to other languages on the surface, deep down it’s actually much different.
The goal of this series is to turn these unexpected behaviors into, for you, something to be expected. And, just perhaps, allow you to catch strange bugs ahead of time.
Understanding how JavaScript operates under the hood can allow you to catch strange bugs ahead of time.
In this article, we’ll be talking about something you may have heard of: the global environment and global object in JavaScript. If you haven’t heard these terms, you will eventually. And, after this, you’ll know exactly what they mean. So what are they exactly?
Funny you should ask.
What are the global environment and global object?
Let’s start the answer to this question by giving a little more context on what we call the execution context. (See what I did there? So funny you forgot to laugh.)
The execution context is, essentially, the code that is currently running. It acts as a “wrapper” around this running code. An example could be a function. When a function is running, it’s acting as the current execution context. However, the execution context can consist of things that you haven’t written in your code, such as the global environment and global object, which we will discuss now.
The most outer wrapper/execution context is the global execution context. When we say “Global” in the world of JavaScript, we’re describing something that is accessible anywhere in your code/not inside a function.
When you run your code, the JavaScript engine automatically creates two of these things for you: the global object and ‘this’.
“Global” describes anything that is accessible anywhere in your code/not inside a function. JavaScript automatically creates two such things for you: the Global Object and ‘this’.
Let’s see this in action
If you want to follow along, in your code editor, try making a generic HTML file that uses a script tag to source from another file called app.js:
Create app.js and leave it totally blank to start.
Now open this file in your browser (I like to use the Live Server extension in VSCode for these kinds of things, but it’s not a necessity.), and open your dev tools console with Option + ⌘ + J (on macOS), or Shift + CTRL + J (on Windows/Linux). (These instructions are for Chrome. If you’re not using Chrome and/or VSCode, a quick Google search will suffice to get to this point).
So, app.js is completely empty, what do you think is going to show up in our dev console? If you said nothing, you’re absolutely right. But wait, JavaScript creates the global object and ‘this’ for us automatically upon execution, so we should be able to access that, right? Yes, let’s take a look at it.
Go ahead and enter ‘this’ into your console. Look what pops up:

Hmmm… Now enter ‘window’:

Even though there was no code in the file, JavaScript was still able to execute it and create a global execution context as well as the global object (‘this’ or ‘window’).
Okay, that’s all well and good. So what happens when we put some code in?
In app.js create a variable with a value, and create an empty function:
Now save the file, refresh the page, and let’s open the dev console again.
Enter ‘window’ again and click the right-facing triangle on the left to expand the object.

Here we see a ton of name/value pairs (objects) and, wait a sec, we see that a
is now in here as well! And for that matter, b()
too! (If you’re following along and you don’t see it in the same spot as the screenshot, scroll down a ways and you should find it.)
When we run this file, a global execution context is created. Since a
and b()
aren’t inside functions (globally accessible), they get attached to the global object.
Anything defined globally is attached directly to the global object.
To prove even further that these are attached to the global object, let’s try entering ‘window.a’ and ‘window.b’ and see what happens.

So, in summary, JavaScript has something called execution contexts, which decide which code is currently running. It has a “global execution context” and a “global object”, which is created for you by the JavaScript engine.
“Global” in JavaScript describes anything that is outside a function. The global object is directly attached to anything you declare globally.
More advanced JavaScript knowledge and how these concepts play into it to come!
If you enjoyed this bite-sized bit of advanced JavaScript knowledge and are looking forward to more, feel free to share!
How has understanding the global environment and global object helped you in your programming?