Sitemap

🧠 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 error

This flexibility might seem convenient, but it often causes accidental overwrites that go unnoticed.

✅ Summary: Why var is Problematic

  • Scope confusion: var ignores 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.

  1. Cannot be Redeclared, but Can Be Reassigned
let name = "Lee";
let name = "Kim"; // ❌ SyntaxError

You can’t declare the same variable name twice with let, but you can update its value:

let count = 1;
count = 2; // ✅ Allowed

2. 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); // ❌ ReferenceError

This 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.

  1. No Redeclaration, No Reassignment
const name = "Lee";
name = "Kim"; // ❌ TypeError

Once declared, a const variable cannot be reassigned or redeclared.

2. Block Scope (Same as let)

{
const msg = "Hello";
}
console.log(msg); // ❌ ReferenceError

3. 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); // ✅ Allowed

To 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 const by default — it signals intent more clearly and prevents accidental changes.
  • Use let only when the variable needs to be reassigned.
  • Avoid using var unless maintaining legacy code.

--

--