This content originally appeared on DEV Community and was authored by Sylwia Laskowska
If youβre learning JavaScript, one of the first questions youβll face is:
Should I use const or let?
And whatβs up with this old thing called var?
It sounds simple, right?
But trust me β as a senior dev whoβs done countless code reviews and technical interviews, I can tell you:
this is one of those βobviousβ things that many developers still get wrong.
So letβs break it down β clearly, practically, and once and for all.
const
β constant, but not always frozen
When you use const
, youβre saying:
βThis variable name will always refer to the same thing.β
Example:
const name = "Alice";
console.log(name); // Alice
name = "Bob"; // ❌ TypeError
You canβt reassign a const
.
But hereβs a fun twist: if itβs an object or array, you can still change its contents
const numbers = [1, 2, 3];
numbers.push(4); // ✅ works
console.log(numbers); // [1, 2, 3, 4]
numbers = [0]; // ❌ can't reassign
const
doesnβt make the value itself immutable β only the reference (the βbox labelβ) is fixed.
If you truly need immutability, use Object.freeze(), but note itβs shallow.
Use
const
by default.
It keeps your code predictable and self-documenting β if something shouldnβt change, make it const.
let
β for things that change
When you do need to reassign a variable, go for let
:
let counter = 0;
counter = counter + 1;
console.log(counter); // 1
You can also use let
inside blocks (if, for, {}):
if (true) {
let message = "Hello!";
console.log(message); // works here
}
console.log(message); // ❌ ReferenceError
Thatβs because let
is block-scoped β it only exists inside the { } where it was declared.
Bonus fact:
Both let
and const
are hoisted, but they live in the Temporal Dead Zone (TDZ) until the code reaches their declaration.
Thatβs why accessing them too early throws a ReferenceError:
console.log(x); // ❌ ReferenceError
let x = 5;
var
β the old-school way (for history lovers)
Before 2015, JavaScript only had var
.
It kind of works like let
, but with some weird, legacy behaviors.
Example:
if (true) {
var name = "Charlie";
}
console.log(name); // ✅ still works outside the block!
Thatβs because var
has function scope, not block scope.
You can even access it before the declaration, due to hoisting:
console.log(a); // undefined
var a = 10;
And hereβs what function scope really means:
function test() {
if (true) {
var greeting = "Hi!";
}
console.log(greeting); // ✅ "Hi!"
}
test();
console.log(greeting); // ❌ ReferenceError
Nowadays, we use
let
and const
instead β but itβs still good to know what var
does.
Youβll definitely encounter it in older codebases.
Quick Summary
Keyword | Can Reassign? | Scope | Hoisted? | Use It? |
---|---|---|---|---|
const |
![]() |
Block | ![]() |
![]() |
let |
![]() |
Block | ![]() |
![]() |
var |
![]() |
Function | ![]() undefined ) |
![]() |
Pro Tip
In modern JavaScript projects (especially with ESLint), youβll often see a rule that says:
βUse const
wherever possible.β
Thatβs not dogma β itβs good hygiene.
It keeps your codebase more predictable and helps tools catch bugs early.
Wrap Up
So, in short:
Use
const
most of the time
Use
let
if you really need to change the value
Avoid
var
unless youβre maintaining ancient code
Keep your variables tidy, your scope clear, and your code modern!
Your turn:
Do you ever still use var
?
Or maybe youβve seen a weird hoisting bug in the wild?
Drop it in the comments β letβs swap battle stories
This content originally appeared on DEV Community and was authored by Sylwia Laskowska