The Difference of “var” vs “let” vs “const” in Javascript
Hello to #SweaterSeason! If you saw this article while Googling, I am going to make a wild guess that you are confused about the difference between var
, let
, and const
in Javascript (JS). No worries, I got you, developer. let
and const
are two new features of ES6, which came out in 2015. Before that, var
was the only way to declare a variable. This is one of the things that I’ve been dying to write a blog about because it could be confusing AND fun at the same time!
A quick disclaimer: This is learning progress for me as well, so bear with me if I am not being clear, because I am writing this using my beginner’s perspective.
Before we start, I will explain these three variables declaration in three aspects: function-scoped & block-scoped, update & redeclaration, and hoisting to highlight the similarities and differences.
Table of Content
var
var
can do so many things since the variable declared under var
can be scoped globally and locally, or you might heard of the term “function scope”. For instance,
var welcome = 'Welcome to Sweater Season!' // globally scopedfunction fallActivities() {
var activities = 'buy a pumpkin and make Jack O Lantern';
// locally scoped
console.log(`You can ${activities}`);
// The `backtick`, a.k.a the template literal, is a new feature in ES6 to replace the complication of string concatenation.}console.log(welcome); // Welcome to Sweater Season!console.log(activities); // ReferenceError: activities is not defined
Global scope means a variable can be scoped outside of the function since it is defined outside of the function, while local scope means a variable is defined inside the function locally, therefore that variable cannot be called outside of the function.
We can also update the var
variable if you want.
var welcome = 'Welcome to Sweater Season';
console.log(welcome); // Welcome to Sweater Season!welcome = 'Pumpkin Spice Latte! Halloween! Red Leaves!';
console.log(welcome); // Pumpkin Spice Latte! Halloween! Red Leaves!
We can redeclare the var
variable as well.
var welcome = 'Welcome to Sweater Season';
console.log(welcome); // Welcome to Sweater Seasonvar welcome = 'Pumpkin Spice Latte! Halloween! Red Leaves!';
console.log(welcome); // Pumpkin Spice Latte! Halloween! Red Leaves!
When hoisting with var
, it will initialize the value of undefined
. I’d like you guys to pay attention to this since that would be a different case for let
and const
. Hoisting is a JS way to call a variable/function on top of the scope before the code is executed.
function fallActivities() {
console.log(activities) // undefined
var activities = 'buy a pumpkin and make Jack O Lantern';
console.log(`You can ${activities}.`); // You can buy a pumpkin and make Jack O Lantern.
}
With the convenience of scoping and updating a var
variable, it is easy to spot when writing a small program, or knowing what one wants to redefine if necessary.
However, what if you have already used the variables in other parts of the code, but you forgot about it! This will create a lot of bugs🐞 for us and probably need to spend hours and hours to debug that one *little* mistake that you make JUST BECAUSE YOU FORGOT THAT YOU HAVE ALREADY USED THE VARIABLE!
This is why… let
and const
are here to save our day! (back to the top)
let
let
is my favorite and the most preferable way for variable declaration. It works quite similar tovar
, except let
is block-scoped. A block is referring to anything within the curly braces {}
.
function greetings() {
let hello = 'Hello Fall!';
console.log(hello); // Hello Fall!
}greetings(); // Hello Fall!
console.log(hello); // ReferenceError: hello is not defined
In other words, if we try to call the variable hello
outside of the block, it will return ReferenceError
.
Like var
, let
can be updated, however, cannot be re-declared.
Yes to update:
let welcome = 'Welcome to Sweater Season';
console.log(welcome) // Welcome to Sweater Seasonwelcome = 'Pumpkin Spice Latte! Halloween! Red Leaves!';
console.log(welcome) // Pumpkin Spice Latte! Halloween! Red Leaves!
But will return an error if try to redeclare:
let welcome = 'Welcome to Sweater Season';let welcome = 'Pumpkin Spice Latte! Halloween! Red Leaves!';
// SyntaxError: Identifier 'welcome' has already been declared
However, if the same variable is declared under a different scope, there will be no error.
let welcome = 'Welcome to Sweater Season';function fall() {
let welcome = 'Pumpkin Spice Latte! Halloween! Red Leaves!';
console.log(welcome);
// Pumpkin Spice Latte! Halloween! Red Leaves!
}fall(); // Pumpkin Spice Latte! Halloween! Red Leaves!console.log(welcome); // Welcome to Sweater Season
The reason is simple because as mentioned above, let
is block-scoped. Anything inside the {}
is considered a block. We can think of the situation like there is a “Charlie Brown” goes to School A, and there is another person also named “Charlie Brown,” but he goes to School B. The school is a scope itself, and they are two different people under the same name.
We can still hoist the let
variable, but we will get a ReferenceError
, instead of undefined
in var
.
//function
function fallActivities() {
console.log(activities) // ReferenceError: Cannot access 'activities' before initialization
let activities = 'buy a pumpkin and make Jack O Lantern';
console.log(`You can ${activities}.`); // You can buy a pumpkin and make Jack O Lantern.
}
At this point, you may still have question about what the difference between function-scoped and block-scoped are. In a nutshell, a var
variable can be scoped outside of the {}
inside of a function:
function fallActivities(activity) {
for (var i = 0; i < activity.length; i++) {
var name = activity[i]
} console.log(i) // 5
console.log(name) // Jack O Lantern
}activity = ['hiking', 'Halloween', 'Pumpkin Patch', 'Read Snoopy Fall Comics', 'Jack O Lantern'];fallActivities(activity);
But if we change the var
to let
:
function fallActivities(activity) {
for (let i = 0; i < activity.length; i++) {
let name = activity[i]
} console.log(i) // ReferenceError: i is not defined
console.log(name)
}activity = ['hiking', 'Halloween', 'Pumpkin Patch', 'Read Snoopy Fall Comics', 'Jack O Lantern'];fallActivities(activity);
Since i
and name
are defined inside the {}
, we will get ReferenceError
when we try to call these two variables outside of the {}
. That’s block-scoped.
I hope that clears out some confusions before we move to const
! :)
const
Since most of the things are covered in let
, I will quickly go over const
.
const
is quite self-explanatory. const
variables maintain constant values. While the nature of const
is quite different from let
, they both share a lot of similarities.
Like let
declarations, const
is block-scoped. I hope the above examples clarify what block-scoped is.
const
declarations, like let
, are not initialized when they are hoisted to the top.
const
cannot be redeclared, just like let
. But the difference from let
is const
cannot be updated.
let welcome = 'Welcome to Sweater Season'
const snoopy = 'Snoopy looks so cute with sweaters!!'welcome = 'Pumpkin Spice Latte! Halloween! Red Leaves!'snoopy = 'Snoopy looks ugly in sweaters!' // TypeError: Assignment to constant variable.
Ooof, Javascript gone mad when you tryna reassign const
variable, so as Snoopy.
Conclusion
Before we say goodbye, let’s sum up what we just discussed:
var
:function-scoped and can be updated and redeclared.
let
: block-scoped, can be updated, but cannot be redeclared.
const
: block-scoped, cannot be updated and redeclared.
It’s always best practice to stick with let
and const
. You may see examples using var
from time to time. But for your sake and your teammates’ sake, just stick with let
and const
to build a better program :)
Alright, go enjoy your PSL and let’s enjoy the beauty of red leaves before the weather gets colder!