JavaScript Pills: var, let and const
This is a post from a series where I share insights from my journey with JavaScript in a mini article format. See all other posts on my profile!
Today, we have three keywords for declaring variables in JavaScript: var
, let
and const
. The keyword var
has always been around, but let
and const
are ES6 additions. The last two have virtually eliminated the need for var
, which has lately become discouraged. Let’s find out why!
The main highlight of using const
is that this type of variable, as the name implies, is constant: it cannot be redeclared and its value cannot be reassigned (this does not mean it is immutable; it can still change through other manipulations). Therefore, the value of every const
must be assigned in the same statement as it was declared, since we cannot assign it later. Here’s what happens when we try to perform an illegal reassignment:
const juice = 'orange';juice = 'apple';
// Error: Assignment to constant variable
However, it is worth noting that, because it's not immutable, if const
keeps an object, its keys and values can be changed normally:
const myObj = { juice: 'orange' };myObj.juice = 'apple';myObj.juice
// 'apple'
Another difference between the three is that declaring a global variable (i.e. outside of a function) with var
automatically adds it as a property of the window
object:
var coffee = 'black';window.coffee === coffee
// true
However, declaring a global variable with let
or const
does not add it to the window
object:
let tea = 'green';window.tea === tea
// false
In addition, both let
and const
declare a local variable within the scope of the block they are inserted into — unlike var
, which ignores the block unless it is a function. A block is considered to be any brace {}
delimited space. Here's an example of how let
behaves in the scope of an if
block:
let myNumber = 1;if (myNumber === 1) {
let myNumber = 2; console.log (myNumber);
// 2
}console.log (myNumber);
// 1
If we look it up from within the if
block, the value of myNumber
is the one that was assigned inside that block: 2
. But if we reference it from outside the block, we have no access to the value that was assigned within it, since the variable is only available in that scope. We can only see the outside value of myNumber
, attributed back at the example's first line: 1
.
The same behaviour applies to const
:
const myNumber = 1;if (myNumber === 1) {
const myNumber = 2; console.log (myNumber);
// 2
}console.log (myNumber);
// 1
This difference between scopes also affects the hoisting of the variables. Any variables declared with var
are hoisted to the top of the function scope in which they were declared (or the global scope if they are not within any function). This means that the declaration (for example, var a
) is executed before any other code, and even before the value is assigned:
function getMood (isHappy) {
if (isHappy) {
var happy = 'Yay!';
} else {
var meh = 'Meh';
}
}
In the above function, if we analyse the hoisting of the variables, this is what is happening in practice:
function getMood (isHappy) {
var happy, meh; if (isHappy) {
happy = 'Yay!';
} else {
meh = 'Meh';
}
}
Can you imagine how this behaviour can return many accidental undefined
's (and migraines)?
Here comes a big advantage of the let
and const
variables: because they consider the block in which they were declared as their scope, they behave differently. If the variable is declared within a block, it is suspended in the “temporal dead zone” until the declaration is processed, instead of being hoisted to the top. Ergo, the variable can only be accessed after its declaration. Sounds safer, right?
We can link this context to yet another particularity of let
and const
: they cannot be redeclared in the same scope and any attempt returns a syntax error. However, redeclaration at different scopes is accepted, because one context does not see the other. Here’s an example of valid code with let foo
declared in two different blocks:
let myValue = 1;switch (myValue) {
case 0: {
let foo;
break;
}
case 1: {
let foo;
break;
}
}
When should we use each type of variable, then?
The decision between let
and const
depends only on whether you intend to reassign the value of this variable. Using const
even improves the readability of your code by making it clear that such a variable is a constant.
In general: scoping, the ability to prevent value reassignment and the consequent reduced freedom in JavaScript (considered excessive by some) makes the use of let
and const
preferred by developers today to prevent accidental changes and breakage. The general convention is that there is no reason to use var
anymore.
Keep in mind that there are still other differences and more advanced features. If you'd like to dive deeper, you should refer to the MDN specifications for let and const.
That’s all for today and see you next time ❤