JavaScript var, let, and const Explained: Scope, Hoisting & Best Practices
everything you need to know about var, let, and const in JavaScript, including scope, hoisting, TDZ, mutability, re-declaration, use cases, and common pitfalls.
1. Scope
var – Function Scope
- Available throughout the entire function in which it is declared.
- Doesn't respect block-level scope (like
if,for, etc.)
let & const – Block Scope
- Only available within the block
{}where they are defined.
2. Hoisting
All three are hoisted (moved to the top of their scope), but behave differently:
| Keyword | Hoisted | Initialized | Access Before Declaration |
|---|---|---|---|
var | Yes | as undefined | Allowed (undefined) |
let | Yes | ❌ No | ❌ Throws ReferenceError |
const | Yes | ❌ No | ❌ Throws ReferenceError |
Temporal Dead Zone (TDZ)
let and const are in a "dead zone" from the start of the scope to where they are declared. You cannot access them before declaration.
3. Re-declaration and Reassignment
| Keyword | Re-declaration (same scope) | Reassignment | Notes |
|---|---|---|---|
var | Allowed | Allowed | May lead to bugs |
let | ❌ Not allowed | Allowed | Safer |
const | ❌ Not allowed | ❌ Not allowed | Constant reference |
4. Mutability
constdoes not make the value immutable, only the binding is constant.- If
constrefers to an object or array, you can mutate its content.
5. Global Object Binding
- Variables declared with
varin the global scope become a property of the global object (windowin browsers). letandconstdo not attach to the global object.
6. Use Cases / Best Practices
| Use Case | Preferred Keyword |
|---|---|
| Value changes over time | let |
| Constant values or references | const |
| Avoid unless legacy support | var |
Use
constby default.
🔄 Switch toletonly when you need to reassign.
❌ Avoidvarin modern code.
7. Interview Pitfalls & Trick Questions
❓ What will this print?
🔸 var is function-scoped. By the time the setTimeout runs, the loop is over, and i is 3.
Fix with let:
8. Summary Table
| Feature | var | let | const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Hoisting | Yes (initialized) | Yes (TDZ) | Yes (TDZ) |
| Use before declaration | Allowed (undefined) | ❌ ReferenceError | ❌ ReferenceError |
| Redeclaration | Yes | ❌ No | ❌ No |
| Reassignment | Yes | Yes | ❌ No |
| Mutable content | Yes | Yes | Yes (objects/arrays) |
| Global object binding | Yes | ❌ No | ❌ No |