Global variables

Global variables are generally considered a bad thing. For the purposes of this guide they will be covered simply for understanding, but developers should typically stay away from them.

thisIsMyVariable = "value for my variable";

console.log(thisIsMyVariable); // value for my variable

In some environments/runtimes the above will not run, it will throw an exception because global variables are considered dangerous. It is often possible to use global variables using window or globalThis as below:

window.thisIsMyVariable = "value for my variable";

console.log(window.thisIsMyVariable); // value for my variable

The main downside to global variables is difficult maintainability. If using global variables there is a risk that the same name is used for variables in different locations accidentally, leading to the wrong variable being accidentally updated or overridden. For this reason it is generally better practice to use scoped variables.

Scoped variables

99.9% of the time you want to be using scoped variables. These are var, let and const. Originally only var existed but in es6 (2015) let and const were introduced. We will cover all three, but in general for new code you will typically want to stick to let and const. var is similar to let, but is slightly different and typically associated with legacy code.

What is scope?

There are a few different flavours of scope, block scopes can be defined with curly brackets {}. They usually accompany if statements, functions or loops. They can however be introduced by themselves, but this is not commonly seen.

The other type of scope that is applicable to var variables is function scope.

Variables created in a specific scope are limited to that scope or child scopes nested beneath it. They will not be available in sibling scopes or parent scopes. This can be seen in the following example, where the second console that is above the scope in which the variable was declared will either show an undefined variable or throw an exception depending on your runtime.

{
  let myVariable = "value";
  console.log(myVariable); // value
}
console.log(myVariable); // undefined

let

let is used to create a variable limited to the current scope that can be reassigned or updated once created, but cannot be re-declared in the same scope.

Basic example

let myVariable = "value";

console.log(myVariable); // value

Variable re-assignment example

let myVariable = "value";

myVariable = "new-value";

console.log(myVariable); // new-value

Variables with the same name should not be declared more than once in the same scope

This is example will run, but will always be frowned upon.

let myVariable = "value";

let myVariable = "new-value";

console.log(myVariable); // new-value

Variable can be declared with the same name in different scopes

Declaring variables in nested scopes with the same name is usually considered ok, but depending on your projects code standards, may be frowned upon.

let myVariable = "value";
{
  let myVariable = "new-value";
  console.log(myVariable); // new-value
}
console.log(myVariable); // value

const

const is similar to let but prevents a variable from being reassigned after it has been declared. To demonstrate this, running the following lines of code will throw an error.

const thisCannotChangeValue = "original";

thisCannotChangeValue = "new";

Throws:

error: Uncaught TypeError: Assignment to constant variable.

var

As mentioned earlier, these are very similar to let but are a bit more legacy. I usually avoid these and migrate them to use let where I come across them and it makes sense. The key difference is the scope to which the variable is created. Unlike let, var creates a variable in the function scope, rather than block scope.

This can be best demonstrated by changing one of our earlier examples for demonstrating let but changing out let for var.

{
  var myVariable = "value";
  console.log(myVariable); // value
}
console.log(myVariable); // value

Unlike let, this variable is scoped to the entirity of the function it resides in. Not the block scope.