The Difference of “var” vs “let” vs “const” in Javascript

Megan Lo
The Startup
Published in
6 min readOct 19, 2020

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!

Source: @Snoopy (Twitter)

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

Source: @mpjme (https://twitter.com/mpjme)

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 Season
var 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!

Source: QuickMeme (http://www.quickmeme.com/meme/3uj5p1)

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 Season
welcome = '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.
}

(back to the top)

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.
Animated Snoopy on fire
Source: Tenor

Ooof, Javascript gone mad when you tryna reassign const variable, so as Snoopy.

(back to the top)

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!

Photo by Patrick Tomasso on Unsplash

(back to the top)

References

--

--

Megan Lo
The Startup

Software Engineer @ Citi | I write about JavaScript.