When you start learning JavaScript, one of the first questions that comes up is: what’s the difference between var, let, and const? All three are used to declare variables, but they behave differently when it comes to scope, re-declaration, hoisting, reassignment, and loops. Understanding these differences is important to write clean and bug-free code. Let’s understand their behavior with simple examples.
1. Scope
- var → Function-scoped. If declared inside a function, it stays inside that function. But if declared inside a block (if, for, etc.), it escapes the block.
- let → Block-scoped. Stays limited to the block
{ }where it is defined. - const → Same as let (block-scoped), but cannot be reassigned.
Example:
function test() {
if (true) {
var x = 10;
let y = 20;
const z = 30;
}
console.log(x); // 10 (works)
console.log(y); // Error
console.log(z); // Error
}
2. Re-declaration
- var → Can be re-declared in the same scope.
- let / const → Cannot be re-declared in the same scope.
Example:
var a = 1;
var a = 2; // Works
let b = 1;
// let b = 2; // Error
const c = 1;
// const c = 2; // Error
3. Hoisting
- var → Hoisted and initialized with
undefined. - let / const → Hoisted but not initialized (Temporal Dead Zone aka TDZ).
Example:
console.log(a); // undefined
var a = 10;
console.log(b); // ReferenceError
let b = 20;
console.log(c); // ReferenceError
const c = 30;
4. Reassignment
- var / let → Can be reassigned.
- const → Cannot be reassigned (but objects/arrays can be mutated).
Example:
var x = 5;
x = 10; // Works
let y = 5;
y = 15; // Works
const z = 5;
// z = 20; // Error
const obj = { name: 'John' };
obj.name = 'Doe'; // Works
// obj = { age: 25 }; // Error
5. Global Object Property
- var → Attaches to
windowin browsers. - let / const → Do not attach to
window.
Example:
var a = 10;
let b = 20;
const c = 30;
console.log(window.a); // 10
console.log(window.b); // undefined
console.log(window.c); // undefined
6. Loops and Async
- var → No new scope in loops (causes async issues).
- let → Creates new scope each iteration (safe in async).
Example:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
} // 3, 3, 3
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 1000);
} // 0, 1, 2
7. const in Loops
- const works with
for...ofloops. - Not allowed in counter loops because it cannot be reassigned.
Example:
for (const i of [1, 2, 3]) {
console.log(i);
} // 1,2,3
for (const k = 0; k < 3; k++) {
console.log(k);
} // Error
8. When to Use
- var → Avoid in modern code.
- let → Use when value changes.
- const → Default choice when value should not be reassigned.
Quick Comparison Table
| Feature | var | let | const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Re-declare | Yes | No | No |
| Re-assign | Yes | Yes | No |
| Hoisting | Yes (undefined) | Yes (TDZ) | Yes (TDZ) |
| Global obj | Yes | No | No |
Final Thoughts
The choice between var, let, and const is simple:
- Avoid var unless working with legacy code.
- Use const by default.
- Use let only when the value needs to change.
👉 Rule of thumb: const first, let when needed, never var.


