JavaScript Variables: var, let, and const Explained
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.
- Block scoped
- Safer in modern code
- Preferred today
- Function scoped
- Older behavior
- More bug-prone
Modern JavaScript usually prefers let and const over var.
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.
if (true) {
var oldWay = "visible outside";
let modernWay = "only inside block";
}
console.log(oldWay); // "visible outside"
// console.log(modernWay); // ReferenceError
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.
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.
console.log(count); // undefined
var count = 5;
// console.log(total); // ReferenceError: Cannot access 'total' before initialization
let total = 8;
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.
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.
let cartTotal = 0;
cartTotal += 25;
cartTotal += 15;
console.log(cartTotal); // 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.
const taxRate = 0.2;
const price = 100;
const finalPrice = price + (price * taxRate);
console.log(finalPrice); // 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.
const isLoggedIn = true;
if (isLoggedIn) {
const welcomeMessage = "Welcome back";
console.log(welcomeMessage);
}
// console.log(welcomeMessage); // ReferenceError
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.
const colors = ["red", "blue"];
colors.push("green");
console.log(colors); // ["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.
for (let i = 0; i < 3; i++) {
console.log(i);
}
// console.log(i); // ReferenceError
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.
const count = 1;
count = 2;
Fix: Use let when the value needs to change after declaration.
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.
console.log(userName);
let userName = "Mia";
Fix: Declare the variable before using it.
let userName = "Mia";
console.log(userName);
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().
const settings = {
theme: "light"
};
settings.theme = "dark";
Fix: Remember that const stops reassignment, not mutation of object contents.
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.
if (true) {
var status = "active";
}
console.log(status); // "active"
Fix: Use let or const when you want block scope.
if (true) {
const status = "active";
console.log(status);
}
// console.log(status); // ReferenceError
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.