# JavaScript Variables: var, let, and const Explained

Source: https://devdocs10.com/articles/javascript/js-variables  
By Murat Bo · Published 2026-05-12 · DevDocs10 (https://devdocs10.com)

JavaScript variables let you store values so your code can reuse, update, and compare data. Understanding `var`, `let`, and `const` is one of the most important JavaScript basics because these keywords affect scope, reassignment, hoisting, and how safe your code is.

> **Quick answer:** In modern JavaScript, use `const` by default, use `let` when a value must change, and avoid `var` in new code. The main differences are scope rules, hoisting behavior, and whether reassignment is allowed.

> **Difficulty:** Beginner
>
> **Helpful to know first:** You'll understand this better if you already know basic JavaScript syntax, simple data types like strings and numbers, and how to run small code examples in the browser console or Node.js.

## 1. What Are var, let, and const?

`var`, `let`, and `const` are JavaScript keywords used to declare variables. A variable gives a name to a value so you can use that value later in your program.

These three keywords do a similar job, but they do not behave the same way. The most important differences are scope, hoisting, and reassignment.

- `var` creates a function-scoped variable and is mostly used in older JavaScript code.
- `let` creates a block-scoped variable that can be reassigned.
- `const` creates a block-scoped variable that cannot be reassigned after its initial value is set.
- `const` does not make objects or arrays fully immutable; it only prevents the variable name from being reassigned.
- In modern JavaScript, `let` and `const` are preferred over `var`.

This topic is often confusing because beginners assume all three are interchangeable. They are not. Choosing the right one helps prevent bugs and makes your code easier to understand.

## 2. Side-by-Side Comparison

The table below shows the practical differences between the three variable declaration keywords.

| Feature | var | let | const |
| --- | --- | --- | --- |
| Scope | Function scope | Block scope | Block scope |
| Can be reassigned | Yes | Yes | No |
| Must be initialized when declared | No | No | Yes |
| Hoisted | Yes | Yes, but not usable before declaration | Yes, but not usable before declaration |
| Can be redeclared in same scope | Yes | No | No |
| Recommended for new code | No | Yes | Yes |

## 3. Key Differences Explained

### Scope

Scope means where a variable is accessible in your code.

`var` is function-scoped, so if you declare it inside a function, it is available anywhere inside that function. It does not respect block boundaries such as `if` statements or loops.

`let` and `const` are block-scoped, so they only exist inside the block where they are declared.

```javascript
if (true) {
  var oldWay = "visible outside";
  let modernWay = "only inside block";
}

console.log(oldWay); // "visible outside"
// console.log(modernWay); // ReferenceError
```

Output (tested with Node 24.21.0):

```text
visible outside
```

This is one reason `let` is safer than `var`. It prevents values from leaking outside the block where they belong.

### Reassignment

Reassignment means giving a variable a new value after it has already been declared.

```javascript
let score = 10;
score = 20;

const siteName = "DevDocs10";
// siteName = "New Name"; // TypeError
```

Use `let` when the value is expected to change. Use `const` when the variable should always point to the same value.

### Hoisting

All three declarations are hoisted, but they do not behave the same way.

With `var`, the declaration is hoisted and initialized with `undefined`. With `let` and `const`, the declaration is hoisted too, but the variable stays in the temporal dead zone until the declaration line is reached.

```javascript
console.log(count); // undefined
var count = 5;

// console.log(total); // ReferenceError: Cannot access 'total' before initialization
let total = 8;
```

Output (tested with Node 24.21.0):

```text
undefined
```

This difference explains why older code using `var` can behave in surprising ways.

### Redeclaration

`var` allows redeclaration in the same scope, while `let` and `const` do not.

```javascript
var message = "Hello";
var message = "Hi";

let user = "Ava";
// let user = "Liam"; // SyntaxError
```

Preventing redeclaration makes accidental bugs easier to catch.

## 4. When to Use Each

You rarely need to ask which keyword is technically possible. The more useful question is which keyword best communicates your intention.

- **Use `const` when:** the variable should not be reassigned, such as configuration values, object references, arrays, and function expressions.
- **Use `let` when:** the variable will change over time, such as counters, loop indexes, or values updated by conditions.
- **Use `var` when:** you are reading or maintaining older code that already uses it. Avoid introducing it in new code unless you have a very specific legacy reason.

> A helpful modern rule is: start with `const`, change to `let` only if reassignment is necessary, and leave `var` for legacy code.

## 5. Code Examples

The examples below show how these keywords behave in realistic situations.

### Example 1: A value that changes over time

A running total is a good case for `let` because the value changes as the program runs.

```javascript
let cartTotal = 0;
cartTotal += 25;
cartTotal += 15;

console.log(cartTotal); // 40
```

Output (tested with Node 24.21.0):

```text
40
```

This works because `let` allows reassignment.

### Example 2: A constant setting

A tax rate is usually a good fit for `const` because you do not want to accidentally point the variable at a different value later.

```javascript
const taxRate = 0.2;
const price = 100;
const finalPrice = price + (price * taxRate);

console.log(finalPrice); // 120
```

Output (tested with Node 24.21.0):

```text
120
```

This code is easier to trust because the names that should stay stable are declared with `const`.

### Example 3: Block scope inside an if statement

This example shows why `let` and `const` help prevent leaking values outside a block.

```javascript
const isLoggedIn = true;

if (isLoggedIn) {
  const welcomeMessage = "Welcome back";
  console.log(welcomeMessage);
}

// console.log(welcomeMessage); // ReferenceError
```

Output (tested with Node 24.21.0):

```text
Welcome back
```

The variable exists only where it is needed, which keeps the surrounding code cleaner.

### Example 4: const with arrays and objects

Many beginners think `const` makes an object or array fully unchangeable. It does not. It only prevents reassignment of the variable itself.

```javascript
const colors = ["red", "blue"];
colors.push("green");

console.log(colors); // ["red", "blue", "green"]
```

Output (tested with Node 24.21.0):

```text
[ "red", "blue", "green" ]
```

The array contents can change, but the variable `colors` cannot be reassigned to a different array.

### Example 5: Why var can be surprising in loops

This is a classic reason modern JavaScript prefers `let` in loops.

```javascript
for (let i = 0; i < 3; i++) {
  console.log(i);
}

// console.log(i); // ReferenceError
```

Output (tested with Node 24.21.0):

```text
0
1
2
```

Because `let` is block-scoped, the loop variable stays inside the loop where it belongs.

## 6. Common Mistakes

### Mistake 1: Reassigning a const variable

A variable declared with `const` cannot be assigned a new value later. Beginners often choose `const` and then try to update it.

**Problem:** This code tries to reassign a constant, which causes a runtime error such as `TypeError: Assignment to constant variable.`

```javascript
const count = 1;
count = 2;
```

**Fix:** Use `let` when the value needs to change after declaration.

```javascript
let count = 1;
count = 2;
```

The corrected version works because `let` allows reassignment.

### Mistake 2: Using let or const before declaration

Developers coming from older JavaScript sometimes expect all hoisted variables to act like `var`. That is not how `let` and `const` work.

**Problem:** This code accesses the variable before its declaration line, causing `ReferenceError: Cannot access 'userName' before initialization`.

```javascript
console.log(userName);
let userName = "Mia";
```

Output (tested with Node 24.21.0):

```text
Uncaught ReferenceError: Cannot access 'userName' before initialization
```

**Fix:** Declare the variable before using it.

```javascript
let userName = "Mia";
console.log(userName);
```

Output (tested with Node 24.21.0):

```text
Mia
```

The corrected version works because the variable is accessed only after it has been initialized.

### Mistake 3: Expecting const to freeze objects or arrays

`const` protects the variable binding, not the internal contents of an object or array.

**Problem:** This code assumes `const` prevents all changes, but object properties can still be updated unless you use an additional technique like `Object.freeze()`.

```javascript
const settings = {
  theme: "light"
};

settings.theme = "dark";
```

**Fix:** Remember that `const` stops reassignment, not mutation of object contents.

```javascript
const settings = {
  theme: "light"
};

// Allowed: changing a property
settings.theme = "dark";

// Not allowed: reassigning the variable
// settings = { theme: "blue" };
```

The corrected explanation works because it matches how `const` actually behaves in JavaScript.

### Mistake 4: Using var inside a block and expecting block scope

Beginners often assume a variable declared inside an `if` block stays inside that block. That is true for `let` and `const`, but not for `var`.

**Problem:** This code leaks the variable outside the block, which can lead to accidental overwrites and confusing behavior.

```javascript
if (true) {
  var status = "active";
}

console.log(status); // "active"
```

Output (tested with Node 24.21.0):

```text
active
```

**Fix:** Use `let` or `const` when you want block scope.

```javascript
if (true) {
  const status = "active";
  console.log(status);
}

// console.log(status); // ReferenceError
```

Output (tested with Node 24.21.0):

```text
active
```

The corrected version works because block-scoped variables stay limited to the block where they were declared.

## 7. Tradeoffs and Edge Cases

- `var` still appears in older tutorials, legacy projects, and older build outputs, so you should be able to read it even if you do not use it in new code.
- `const` requires an initial value at declaration time. Writing `const value;` causes a syntax error.
- `let` and `const` are block-scoped, which is usually helpful, but it also means a variable can disappear sooner than a beginner expects.
- Using `var` at the top level in browsers can create behavior tied to the global environment that differs from `let` and `const`.
- `const` does not make nested data immutable. If you need stronger protection, you may need patterns such as copying data or using `Object.freeze()` carefully.
- Loop behavior is often safer with `let`, especially when each iteration should have its own separate variable binding.

## 8. Decision Guide

If you are unsure which one to choose, use this simple guide:

- If the variable should never be reassigned, use `const`.
- If the variable will be updated later, use `let`.
- If you are working in modern JavaScript and are about to type `var`, stop and ask whether `let` or `const` is the better choice. It usually is.
- If you are reading older code, understand that `var` may behave differently because of function scope and hoisting to `undefined`.

> A practical habit is to write `const` first. If JavaScript later needs reassignment, change it to `let`.

## 9. Key Points

- `var` is function-scoped and should usually be avoided in new JavaScript code.
- `let` is block-scoped and is the right choice for variables that change.
- `const` is block-scoped and is the preferred choice for variables that should not be reassigned.
- `let` and `const` cannot be used before initialization without causing a reference error.
- `const` does not make arrays and objects fully immutable.
- Modern JavaScript style usually means using `const` by default and `let` only when needed.

## 10. Final Summary

`var`, `let`, and `const` all declare variables, but they communicate different intentions and follow different rules. The biggest differences are scope, reassignment, hoisting behavior, and redeclaration. These differences matter because they affect whether your code is predictable or bug-prone.

In modern JavaScript, the safest approach is usually to use `const` for stable bindings and `let` for values that must change. Treat `var` as something you should understand for legacy code rather than something you should choose for new code. A good next step is to practice variable declarations inside functions, loops, and conditionals so the scope rules become natural.

## Browser Support

| Feature | Status | Chrome | Edge | Firefox | Safari | Safari iOS |
| --- | --- | --- | --- | --- | --- | --- |
| Let and const | Widely available since Mar 2019 | 49+ | 14+ | 44+ | 10+ | 10+ |

Data: web-features 3.43.0 (MDN Baseline).
