🧠 Understanding var, let, and const in JavaScript
In JavaScript, there are three main ways to declare variables: var, let, and const.
Although the official documentation explains this in a rather complex way, in practice, most developers tend to use let and const.
When I first started learning development on my own, I kept seeing these three variable types everywhere — and I often found myself wondering:
“What’s the actual difference between them?”
If you’ve ever had a similar thought, this post is for you.
Let’s break down what makes each declaration type unique, when to use them, and why modern JavaScript development favors let and const over var.
🟡 Why We Don’t Use var Anymore
var is the oldest way to declare variables in JavaScript.
Before ES6 (released in 2015), let and const didn’t exist, so we had no choice but to use var.
However, var comes with several pitfalls that make it unreliable in modern code. Let’s take a closer look:
1. Function Scope (not Block Scope)
Variables declared with var are function-scoped, not block-scoped. This means even if you declare a var inside an if or for block, it’s still accessible outside that block:
if (true) {
var message = "Hello";
}
console.log(message); // "Hello"This can easily lead to bugs where variables are unintentionally accessed or overwritten from outside their intended context.
2. Hoisting with Implicit undefined
var declarations are hoisted to the top of their scope, and are initialized with undefined. This means you can reference a variable before its declaration — but the result will be undefined, which often leads to confusing bugs.
console.log(a); // undefined
var a = 10;3. Can Be Redeclared (No Error)
You can redeclare the same variable multiple times using var, and JavaScript won’t complain:
var nickname = "foo";
var nickname = "bar"; // ✅ No errorThis flexibility might seem convenient, but it often causes accidental overwrites that go unnoticed.
✅ Summary: Why var is Problematic
- Scope confusion:
varignores block boundaries - Hoisting issues: Accessing before declaration returns
undefined - Redeclaration allowed: Leads to unintended overwrites
This is why most modern developers avoid using var entirely.
🟢 let – The New Standard
Introduced in ES6, let was designed to fix the problems caused by var. Today, it’s the most commonly used variable declaration method.
- Cannot be Redeclared, but Can Be Reassigned
let name = "Lee";
let name = "Kim"; // ❌ SyntaxErrorYou can’t declare the same variable name twice with let, but you can update its value:
let count = 1;
count = 2; // ✅ Allowed2. Block Scope
Get Logan Lee’s stories in your inbox
Join Medium for free to get updates from this writer.
Variables declared with let are only accessible within the block they’re defined in:
if (true) {
let message = "Hello";
}
console.log(message); // ❌ ReferenceErrorThis makes your code more predictable and safer.
3. Hoisting + TDZ (Temporal Dead Zone)
let variables are hoisted like var, but they are not initialized until the declaration line is reached. Trying to access them beforehand throws a ReferenceError:
console.log(a); // ❌ ReferenceError
let a = 10;This inaccessible window before initialization is known as the Temporal Dead Zone (TDZ) — a feature designed to help you catch bugs earlier.
🔵 const – For Values That Never Change
const was also introduced in ES6 and is used for values that should never change after being set.
- No Redeclaration, No Reassignment
const name = "Lee";
name = "Kim"; // ❌ TypeErrorOnce declared, a const variable cannot be reassigned or redeclared.
2. Block Scope (Same as let)
{
const msg = "Hello";
}
console.log(msg); // ❌ ReferenceError3. TDZ Applies Here Too
Just like let, const also has a TDZ. Accessing the variable before declaration throws a ReferenceError.
console.log(score); // ❌ ReferenceError
const score = 100;⚠️ Important: Objects and Arrays Are Mutable
While const prevents reassignment, it does not freeze the contents of an object or array:
const user = { name: "Lee" };
user.name = "Kim"; // ✅ Allowed
const numbers = [1, 2, 3];
numbers.push(4); // ✅ AllowedTo make objects fully immutable, use Object.freeze().
❗ Must Be Initialized at Declaration
Unlike let, const must be initialized when declared:
const age; // ❌ SyntaxError🧠 What Is TDZ (Temporal Dead Zone)?
The TDZ is the time between a variable’s hoisting and its actual declaration in the code.
During this time, the variable exists in memory but cannot be accessed — attempting to do so will throw a ReferenceError.
console.log(name); // ❌ ReferenceError
let name = "Alice";This behavior applies to both let and const, and it makes your code more reliable by failing early when you make a mistake.
✅ When to Use What?
- Use
constby default — it signals intent more clearly and prevents accidental changes. - Use
letonly when the variable needs to be reassigned. - Avoid using
varunless maintaining legacy code.





