🔭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
varis 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: WaterSurprisingly, 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: MilkRemark
This shows that
varis 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 variableand
const point = {x: 1, y: 1};
point.x = 2; // ✅OK
point = {x:0, y:0}; //❌TypeError: Assignment to constant variableDo 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.