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
const
does not make the value immutable, only the binding is constant.- If
const
refers to an object or array, you can mutate its content.
5. Global Object Binding
- Variables declared with
var
in the global scope become a property of the global object (window
in browsers). let
andconst
do 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
const
by default.
🔄 Switch tolet
only when you need to reassign.
❌ Avoidvar
in 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 |