Knowledge Base/concepts/let vs const in JavaScript

let vs const in JavaScript

The difference between let and const in JavaScript is reassignment. Not importance, not seriousness, not whether the value is an object, and definitely not whether the code looks professional enough. const means the binding cannot be pointed at a different value after it is initialized. let means the binding can be reassigned.

That distinction is small, but it cleans up a surprising amount of beginner confusion.

Contents

The short rule

Use const when the variable should keep pointing at the same value.

const courseName = "JavaScript Foundations";
const maxRetries = 3;
const users = ["Ada", "Grace"];

Use let when the variable needs to be reassigned.

let syncStatus = "waiting";

syncStatus = "synced";

That is the rule. The rest of the article is mostly about the places people accidentally add extra mythology.

You can practice the basic decision in the Choose the Keyword exercise.

const blocks reassignment

A const variable must be initialized when it is declared, and it cannot be reassigned later.

const planName = "Starter";

planName = "Pro";
// TypeError: Assignment to constant variable.

JavaScript is protecting the binding named planName. Once that name points to "Starter", the same name cannot be redirected to "Pro".

This is why const works well for fixed labels, configuration values, imported helpers, DOM references, and intermediate results that should not be replaced later.

const price = 75;
const quantity = 3;
const subtotal = price * quantity;

console.log(subtotal); // 225

subtotal is calculated once. If it should not be recalculated by assigning a new value to the same variable, const says so.

const does not freeze objects

This is the classic trap:

const profile = {
  name: "Ada",
  role: "admin",
};

profile.role = "editor";

console.log(profile.role); // "editor"

That code is allowed. The profile binding still points at the same object. The object changed, but the variable was not reassigned.

This is not allowed:

const profile = {
  name: "Ada",
  role: "admin",
};

profile = {
  name: "Grace",
  role: "editor",
};
// TypeError: Assignment to constant variable.

If you need to prevent object changes, const is not enough. You need a different technique, such as creating new objects instead of mutating old ones, or using Object.freeze() for shallow runtime protection.

const settings = Object.freeze({
  theme: "dark",
});

settings.theme = "light";
// TypeError in strict mode. In non-strict scripts, the assignment is ignored.

console.log(settings.theme); // "dark" if the script continues

Even Object.freeze() is shallow. Nested objects can still change unless they are frozen too. Tiny language footnote, enormous source of false confidence. A classic.

Use let for changing state

Use let when reassignment is part of the meaning of the code.

let retries = 0;

retries = retries + 1;
retries = retries + 1;

console.log(retries); // 2

A retry count changes. A loading status changes. A selected tab changes. A running total changes. Those are honest let cases.

let status = "idle";

status = "loading";
status = "success";

The mistake is using let because a value feels temporary:

let fullName = `${firstName} ${lastName}`;

If fullName is never reassigned, const is clearer:

const fullName = `${firstName} ${lastName}`;

Temporary and mutable are different ideas. A value can be short-lived and still not change.

The Fix the Counter exercise focuses on this exact bug: a variable declared with const but updated like state.

Both let and const are block scoped

let and const are block scoped. A block is a pair of braces.

if (true) {
  const message = "inside";
  let count = 1;
}

console.log(message);
// ReferenceError: message is not defined

Variables declared inside the block are not available outside it.

That makes let and const safer than var, which uses function scope and can leak out of blocks.

if (true) {
  var oldStyle = "visible outside";
}

console.log(oldStyle); // "visible outside"

Modern JavaScript code almost always prefers let and const over var. The real choice is usually between const and let, with var left for reading older code and learning why older code occasionally looks like it made a bet with chaos.

const inside loops is normal

People sometimes avoid const in loops because the value changes on each iteration. The trick is that each iteration gets a new binding.

const names = ["Ada", "Grace", "Linus"];

for (const name of names) {
  console.log(name);
}

name is not reassigned inside one loop iteration. The loop creates a fresh name binding for each item.

Use let for the loop counter in a traditional for loop because the counter is reassigned:

for (let index = 0; index < names.length; index += 1) {
  console.log(names[index]);
}

Use const for each item in a for...of loop when you do not reassign the item variable:

for (const name of names) {
  console.log(name.toUpperCase());
}

The for...of guide covers that loop style in more detail.

When to choose each one

This table is boring in the best possible way:

SituationUseExample
Fixed valueconstconst taxRate = 0.13;
Calculated resultconstconst total = price * quantity;
Object or array reference that is not replacedconstconst items = [];
Counter that changesletlet attempts = 0;
Status that changesletlet status = "idle";
Value filled in laterletlet selectedUser = null;
Traditional loop counterletfor (let i = 0; i < 3; i += 1)

One useful habit is to start with const. If you need reassignment, change that variable to let.

const productName = "Workshop Pass";
const unitPrice = 75;
let quantity = 2;

quantity = quantity + 1;

const subtotal = unitPrice * quantity;

That habit gives each variable a sharper meaning. productName, unitPrice, and subtotal are stable. quantity is the moving piece.

Key Takeaways

  • const prevents reassignment of the variable binding. It does not make objects or arrays immutable.
  • let is for variables whose value changes over time.
  • Start with const, then use let when reassignment is part of the code's meaning.
  • let and const are block scoped, which makes them safer than var for modern JavaScript.
  • const is normal inside for...of loops because each iteration gets a fresh binding.
Share this article:
javascriptfundamentalsvariablesscope