
Letβs make it super clear by comparing var
, let
, and const
in JavaScript.
π var
vs let
vs const
Feature | var | let | const |
---|---|---|---|
Scope | Function-scoped | Block-scoped { } | Block-scoped { } |
Hoisting | β
Hoisted (initialized as undefined ) | β Hoisted (but TDZ β error if accessed before declaration) | β Hoisted (but TDZ β error if accessed before declaration) |
Redeclaration | β Allowed | β Not allowed | β Not allowed |
Reassignment | β Allowed | β Allowed | β Not allowed |
Initialization | Optional (defaults to undefined ) | Optional | Mandatory (must assign a value) |
Use in Loops | Problematic (no block scope) | Safe | Safe |
Best Use Case | Old/legacy code | Variables that may change | Constants / Fixed values |
πΉ Examples
1οΈβ£ var
Example (Function-scoped, Redeclarable)
var x = 10;
var x = 20; // β
Redeclaration allowed
console.log(x); // 20
β Problem: It leaks outside block scope
if (true) {
var city = "Delhi";
}
console.log(city); // β
Works (not block-scoped, unsafe)
2οΈβ£ let
Example (Block-scoped, Reassignable)
let age = 20;
age = 21; // β
Reassignment allowed
// let age = 22; β Error (no redeclaration in same scope)
console.log(age); // 21
Safe in loops:
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// β
Output: 0, 1, 2
3οΈβ£ const
Example (Block-scoped, Fixed Reference)
const PI = 3.14159;
// PI = 3.15; β Error (cannot reassign)
console.log(PI); // 3.14159
But objects/arrays inside const
can still be modified:
const person = { name: "Raj", age: 20 };
person.age = 21; // β
Allowed
// person = {}; β Error (cannot reassign object reference)
console.log(person); // { name: 'Raj', age: 21 }
π― Real-Life Analogy
var
β Old container with holes (not safe, things leak out).let
β New box you can reopen and change items inside.const
β Sealed box, you cannot replace it, but you can rearrange items inside (for objects/arrays).
β Which One Should You Use?
- Use
const
by default. - Use
let
if you know the value will change. - Avoid
var
(only for legacy/old code).