JS CodeLab

JavaScript Variables Explained: let vs const vs var

By JS CodeLab Engineering Team•Last updated: October 12, 2026•5 min read

Direct Answer & Key Concept

A JavaScript variable is a named storage container for holding data values in memory. Modern JavaScript uses const by default for immutable bindings and let for variables that must be reassigned, completely replacing the obsolete function-scoped var keyword.

Runnable Code SnippetRun in Playground
// Modern Variable Declaration Best Practices
const API_BASE_URL = "https://api.example.com";
let currentRetryCount = 0;

function incrementRetry() {
  currentRetryCount += 1;
  const isMaxReached = currentRetryCount >= 3;
  return { currentRetryCount, isMaxReached };
}

console.log(incrementRetry()); // { currentRetryCount: 1, isMaxReached: false }
console.log(incrementRetry()); // { currentRetryCount: 2, isMaxReached: false }

What is a variable in JavaScript?

A JavaScript variable is a symbolic container used to store, retrieve, and manipulate data values in computer memory throughout an application's lifecycle. Since the ECMAScript 2015 (ES6) specification, JavaScript provides three declaration keywords—const, let, and the legacy var—each governed by distinct scoping rules, temporal dead zones, and mutability guarantees.

Understanding how JavaScript variables work is essential because incorrect scoping or accidental global assignments are among the most common sources of bugs in web development.


How do let, const, and var differ?

The table below contrasts the fundamental behavior of JavaScript's variable declaration keywords across scope boundaries, hoisting lifecycle, and reassignment constraints:

| Keyword | Scope Level | Reassignable? | Re-declarable? | Hoisting Behavior | Temporal Dead Zone (TDZ)? | | :--- | :--- | :--- | :--- | :--- | :--- | | const | Block ({}) | No (constant reference) | No | Hoisted (uninitialized) | Yes | | let | Block ({}) | Yes | No | Hoisted (uninitialized) | Yes | | var | Function / Global | Yes | Yes | Hoisted (initialized to undefined) | No |

When should you use const?

Use const by default for every variable declaration in your codebase. Declaring with const prevents accidental reassignment and immediately signals to teammates and compilers that the identifier binding will not change. Crucially, while a const reference cannot be reassigned, the internal properties of objects or elements of arrays declared with const can still be mutated unless protected with Object.freeze().

When should you use let?

Use let exclusively when you know a variable must be reassigned later in its lexical lifecycle. Typical use cases include loop counters (for (let i = 0; ...)), mathematical accumulators, and toggles within conditional branching.

Why should you avoid var in modern JavaScript?

The legacy var keyword is function-scoped rather than block-scoped and leaks outside of if statements and for loops. Furthermore, var allows dangerous re-declarations within the same scope and silently initializes hoisted variables to undefined, which can mask syntax errors and introduce elusive race conditions.


What is Block Scope vs Function Scope?

In JavaScript, block scope means a variable declared inside a pair of curly braces { ... } (such as inside an if statement, while loop, or switch block) exists only inside that specific block and cannot be accessed from outside.

if (true) {
  let blockScoped = "I live only inside this if block";
  var functionScoped = "I leak outside this if block!";
}

console.log(functionScoped); // Prints: "I leak outside this if block!"
// console.log(blockScoped); // ReferenceError: blockScoped is not defined

Both let and const strictly enforce block scoping, guaranteeing that temporary loop counters and condition variables do not leak into surrounding application logic.


What is the Temporal Dead Zone (TDZ)?

The Temporal Dead Zone (TDZ) is the period between entering a lexical scope and the actual line of code where a let or const variable is declared. Accessing the variable during this window throws an immediate ReferenceError.

// Attempting to access before declaration
// console.log(userScore); // ReferenceError: Cannot access 'userScore' before initialization

let userScore = 95; // Scope initialized here
console.log(userScore); // 95

Unlike var, which initializes to undefined during hoisting, the TDZ actively prevents developers from reading uninitialized state before its intended declaration point.


Common Mistakes with JavaScript Variables

  1. Reassigning a const identifier: Attempting const port = 3000; port = 8080; causes an unrecoverable TypeError: Assignment to constant variable.
  2. Confusing const reference with deep immutability: Declaring const config = { theme: 'dark' }; allows config.theme = 'light'. Use Object.freeze() if true property immutability is required.
  3. Accidental global variable creation: Forgetting a declaration keyword in non-strict mode assigns the variable to the global window or globalThis object, polluting global state.
  4. Variable shadowing: Declaring a variable with the same identifier in an inner scope obscures the outer variable, creating confusion during maintenance.

Frequently Asked Questions About JavaScript Variables: let vs const vs var

What is the core difference between let and const in JavaScript?

The keyword const creates an immutable binding that cannot be reassigned after declaration, whereas let creates a mutable binding that permits value reassignment within its enclosing block scope.

Can you modify an object or array declared with const?

Yes. Declaring an object or array with const protects the variable reference from being reassigned to a new memory address, but the properties or elements inside the object can still be modified or added.

Why does accessing a let variable before declaration throw ReferenceError?

Variables declared with let and const are placed in the Temporal Dead Zone (TDZ) from the start of the block until the execution reaches the declaration line. Accessing them during the TDZ causes a ReferenceError.

Is var ever still needed in modern JavaScript development?

No. Modern JavaScript standards and style guides universally recommend avoiding var in favor of const and let because var lacks block scoping and causes unintended variable hoisting side effects.

Related Runnable JavaScript Examples

Ready to test what you learned?

The best way to solidify your JavaScript skills is by writing and running code. Open our free online compiler and test your scripts with real-time console feedback.

Open JavaScript Compiler