What exactly makes a framework?

  • Last updated on 16th Oct 2022

In this post, I’ll write about the different behaviors javascript has for global variables.

Introduction

Global scope is weird because each environment handles scopes differently. As a result, it’s important for us to be aware of the differences in order to avoid any potential problems.

The browser window

With respect to the treatment of the global scope, the most pure environment JS can be run in is as a standalone js file loaded in a web page environment in a browser. I don’t mean “pure” as in nothing automatically added—lots MAY be added!— but rather in terms of minimal intrusion on the code or interference with its expected global scope behavior. Below we can see the normal and expected implication:

let studentName = 'Natan'

function hello() {
  console.log(_Hello, ${studentName}!_)
}

hello()

// Hello, Natan!

Then, we can access the property name from the global object window in the outermost scope:

var studentName = 'Natan'

function hello() {
  console.log(_Hello, ${window.studentName}!_)
}

window.hello() // Hello, Natan!

When code is loaded in a web page environment, it is declared in the global scope. This means that if you access the global object, you will find properties of the same names there. The default behavior one would expect from a reading of the JS specification is that the outer scope is the global scope and studentName is legitimately created as global variable. However, this may not always be the case in all JS environments you encounter.

Brief note about shadowing global variables

Shadowing is important because when a variable is shadowed, there is an obstruction. This obstruction, prevents any variables defined inside a function with the same name as the global variable to be accessed from outside the global scope. Below we can see the shadowing of item inside the function scope.

let item = 'Fries'

function printItem(item) {
  item = item.toUpperCase()
  console.log(item)
}

printItem('cheese')
// CHEESE

printItem(item)
// FRIES

console.log(item)
// Fries

Shadowing a global variable means defining a local variable in an inner scope (below it’s also a function level scope) with the same name as a global variable. In this case, the local variable is used instead of the global variable.

One thing to keep in mind is that var cannot shadow let. For example:

function anything() {
var exceptionCase = "word-blah-blah-blah";

{

        let exceptionCase = "ok"; // this is some fine shadowing
        // ..
    }

}

This will throw an error:

function anything() {
let exceptionCase = "wordle";
{

        var exceptionCase = "ok"; // A syntax error will be thrown
        // ..
    }

}

With this we know that there could be such a thing as…

Global Shadowing Another Global

window.anything = 'Wordle'

let anything = 'Monopoly'

console.log(anything)
// Monopoly

console.log(window.anything)
// Wordle

Here, let anything variable is added as a global variable, not a property of the global object. Whereas window.anything is a property of the global object. However, here the shadowing occurs because the anything lexical identifier shadows the something global object property. Or, in other words, the let anything global variable shadows the window.anything global object property.

DOM Global Objects

Whenever you create a DOM element with an id attribute, a global variable that references that DOM element node is created.

<ul id="order">
  <li id="fries-and-condiments">fries w/ sweet mustard condiments</li>
  ..
</ul>
window['fries-and-condiments']
// referencing...
// <li id="fries-and-condiments">fries w/ sweet mustard condiments</li>

Above, you could see the behavior of the browser environment registering all id attributes. This is because the browser environment is the most pure environment JS can be run in. It’s the most pure because it’s the most minimal in terms of interference with the code’s expected global scope behavior.

meme-earth-global

Ending Thoughts

In this article I briefly described global shadowing, global variables, and how they are affected by different execution environments. There is more on this vast topic, and it’s scaling across different types of environments. In my next article, as a followup to this one, I will go into more detail. I hope this article helped you see how the global has different behaviors in different environments, so that you can avoid global shadowing in your code and make your code’s global scope behave as expected.

Resources:

Global Global Property