🔭At a Glance
Feature | var | let | const |
---|---|---|---|
Scope | function-scoped / globally-scoped | block-scoped | block-scoped |
Mutability | mutable (can reassign) | mutable (can reassign) | immutable (cannot reassign) |
Hoisting | hoisted, initialized to undefined | hoisted, not initialized | hoisted, not initialized |
Use Case | legacy code (avoid in modern JS/TS) | changing values | constants |
📜Golden Rule
Use const
first → let
when needed → var
never (unless maintaining old code).
Intro
As a developer with a background in C/C++/C#, I’m familiar with the concept of variable declarations and scoping. However, JavaScript’s features left me confused😵. After reading a few articles, I decide to write down what I’ve learned.
Scope
Let’s start with scope. Scope refers to where the variable name is meaningful. Variables defined with let
and const
are both block-scoped, meaning they are only valid within the { }
. In contrast, the var
is function-scoped(defined inside a function) and global-scoped(defined outside a function).
So what?
OK. I know the
var
is not block-scoped. But why does it matter?
Look at the following code. What do you think the output will be?
var message = "Milk";
var decider = 13;
if (decider > 10) {
var message = "Water";
}
console.log(message); //OUTPUT: Water
Surprisingly, the output is “Water” but not “Milk”🤯! This is strange for a C++ developers as they are pretty sure the output should be “Milk” due to variable shadowing!
auto message = "Milk";
auto decider = 13;
if (decider > 10) {
auto message = "Water";
}
std::printf(message); //OUTPUT: Milk
Remark
This shows that
var
is not block-scoped. It leaks through{ }
blocks like water through a sieve.
Mutability
Remark
In this section, I would not address redeclaration as I prefer not to redeclare any variables.
When it comes to mutability, I always prefer const
. However, there is a subtle detail about the const
. See the following code
const PI = 3.14159;
PI = 3.14; //❌TypeError: Assignment to constant variable
and
const point = {x: 1, y: 1};
point.x = 2; // ✅OK
point = {x:0, y:0}; //❌TypeError: Assignment to constant variable
Do you see a similarity to const
in C++? From my perspective, this looks similar to the const
pointer.
struct Person
{
string name;
int age;
};
//✅OK
Person* const p1 = new Person{.name = "John", .age = 21};
p1->name = "Jane";
//❌NO
p1 = new Person{.name = "John", .age = 21};
Hoisting
What you see is “hoisting” not “hosting”. Simply put, hoisting hides your mistake! When your code is like this:
console.log(writer);
var writer = "Shakespeare";
It actually works like so:
var writer;
console.log(writer); //writer is undefined
writer = "Shakespeare";
The code will run, but the value will be incorrect! The benefit using const
or let
is that they will throw an error instead of hiding the problem.