var, let & const - an introduction
This post is part of learning ES6 series.
Let's look at the differences between var
, let
, and const
in ES6 today. var
, let
, and const
are different ways of declaring variables in JavaScript. var
has been around since the beginning, and let
and const
were introduced recently in 2015.
VAR
In order to understand what benefits let
and const
provide, you have to understand the quirks of var
which has led to many subtle (and many not so subtle) bugs.
Problem #1 - redeclaring variables
You can re-declare a variable using var
and the compiler won't yell at you for doing this. 🤨
Re-declared the variable length without breaking a sweat
This is problematic especially for short lived variables like the ones used in loops( i, j, k), because you can end up accidentally re-using the values assigned to the previously declared variable.
Problem #2 - scoping var
variables
var
variables are scoped to the "current execution context" i.e. the variable's enclosing function or the global scope. It is NOT a block scoped variable. Let's look at an example to make this clear.
To make the var
function scoping concept more concrete, if you try to access the variable i
outside the varTest()
function, the compiler will throw an error.
Problem #3.1 - Accidentally scoping the variable to the global scope
It is very easy to create a var
variable against the incorrect scope, here we've created a global variable attached to the window
object - seniorityLevel.
This happens because var
variables (outside of a function) are attached to the global window object.
Problem #4 Use it before you declare aka Temporal Dead Zone
With var
you can be a magician and use a variable before it even exists.
Now, let’s see how let
and const
address these problems.
LET
Re-declaration
You cannot re-declare let
variables within the same execution context. If you try to do this, the compiler will tell you off.
However, you can re-declare let
variables, if they are in different execution contexts (fancy way of saying different blocks or functions). What does this mean? The following example will run fine without any issues:
As expected, since the variable winner
is re-declared, it does not say true
in the final console.log(). This is because they are scoped differently, the winner
on line 11 is scoped to the window object and the winner
on line 15 is scoped to the if block.
As an exercise for you, dear readers, change the
let
inside of the if block tovar
to see what the compiler does. Will it throw an error message or will it work (silently)?
Scoping
let
is block-level scoped instead of function or globally scoped. If we take the same example as var
above and use let
instead, we get an error as we should.
And no more leaking of for
loop variables.
It doesn't just avoid issues like these described above, it also gives us an easy way to create block level "private" variables like this:
By using let
you can say goodbye to all those pesky var
bugs, including the temporal dead zone bug, because you cannot use or reference a let
variable before declaring it.
CONST
const
has the same features as let
- it's block scoped and cannot be re-declared within the same execution context, however (as the name suggests), you use const
to declare CONSTANTS (i.e. variables whose values don't change).
There is a subtlety that you need to be aware of. const
is not about immutability (that gets all the functional programmers unnecessarily excited), instead it creates an immutable binding.
If a const
variable is assigned to an array or an object, you can still change the values of the object's properties and add / remove values to the array.
The thing that's immutable in both examples above is the binding. const
guarantees that no rebinding will happen once it assigns a value to a variable name. In the case of arrays and objects, their internal state can change.
Note: If you want to declare a
const
whose binding and internal state is truly immutable, you can use Object.freeze() to achieve this outcome.
CONCLUSION
In summary, let
and const
are a safer (and IMHO a better) way to declare variables in JavaScript. Before let
and const
were added to the ECMAScript specification, you would get around the var
issues by using hacks like IIFE to isolate variable declarations so that they don't (inadvertently) pollute the global object name-space.
Unless you have a requirement to support very old browsers, I'd strongly suggest avoiding var
like the plague. You don't need it anymore as you have safer alternatives in the form of let
and const
.
I like (and recommend) Mathias's approach to using var
, const
, and var
as follows:
use
const
by defaultonly use
let
if rebinding is needed(
var
shouldn’t be used in ES2015+)
Thanks for taking the time to read this post, if you found it useful and if you have any comments or tips, please hit me up on twitter (@anup).