🧭Beginner’s (and Not-So-Beginner’s) Guide #3 β€” const vs let (and a bit about var): What Developers Keep Getting Wrong



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 ❌ No Block βœ… (TDZ) βœ… Default
let βœ… Yes Block βœ… (TDZ) βœ… When value changes
var βœ… Yes Function βœ… (initialized as undefined) 🚫 Avoid (legacy)

πŸ’‘ 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