In JavaScript, const
, let
, and var
are all used to declare variables, but they differ in terms of scope, mutability, and hoisting behavior. Below is a detailed comparison:
1. var
- Scope: Function-scoped.
- Variables declared with
var
are scoped to the nearest function block or globally if declared outside any function.
- Variables declared with
- Hoisting: Hoisted to the top of their scope.
- The variable declaration is moved to the top of its scope during the compilation phase, but it is initialized with
undefined
. This means you can reference the variable before its declaration, but it will beundefined
.
- The variable declaration is moved to the top of its scope during the compilation phase, but it is initialized with
- Re-declaration: Can be re-declared within the same scope.
- Mutability: Variables declared with
var
can be reassigned.
Example:
console.log(x); // undefined (hoisted but not initialized) var x = 10; console.log(x); // 10 function test() { var y = 20; if (true) { var y = 30; // Re-declaring inside the block console.log(y); // 30 } console.log(y); // 30 (function-scoped) } test();
2. let
- Scope: Block-scoped.
- Variables declared with
let
are scoped to the nearest enclosing block (e.g.,{}
).
- Variables declared with
- Hoisting: Hoisted but not initialized.
let
variables are hoisted to the top of their block, but they are in a "temporal dead zone" (TDZ) until their declaration is encountered. Accessing them before declaration results in aReferenceError
.
- Re-declaration: Cannot be re-declared within the same scope.
- Mutability: Variables declared with
let
can be reassigned.
Example:
console.log(a); // ReferenceError: Cannot access 'a' before initialization let a = 5; if (true) { let b = 10; console.log(b); // 10 } console.log(b); // ReferenceError: b is not defined (block-scoped)
3. const
- Scope: Block-scoped.
- Like
let
,const
variables are scoped to the nearest enclosing block.
- Like
- Hoisting: Hoisted but not initialized.
- Similar to
let
,const
variables are also in the "temporal dead zone" until their declaration is encountered.
- Similar to
- Re-declaration: Cannot be re-declared within the same scope.
- Mutability: Immutable binding (but not necessarily immutable value).
- Once a variable is assigned a value with
const
, it cannot be reassigned. However, if the value is an object or array, its contents can still be modified.
- Once a variable is assigned a value with
Example:
const c = 15; c = 20; // TypeError: Assignment to constant variable. const obj = { name: "Alice" }; obj.name = "Bob"; // Allowed (modifying the object's property) console.log(obj); // { name: "Bob" } const arr = [1, 2, 3]; arr.push(4); // Allowed (modifying the array's content) console.log(arr); // [1, 2, 3, 4]
Key Differences Summary
| Feature | var
| let
| const
|
|--------------------|--------------------------------|--------------------------------|---------------------------------|
| Scope | Function-scoped | Block-scoped | Block-scoped |
| Hoisting | Hoisted and initialized as undefined
| Hoisted but in TDZ | Hoisted but in TDZ |
| Re-declaration | Allowed | Not allowed | Not allowed |
| Reassignment | Allowed | Allowed | Not allowed (binding is fixed) |
Best Practices
- Use
const
by default for variables whose values do not change after initialization. - Use
let
when you need to reassign the variable. - Avoid using
var
in modern JavaScript due to its function-scoping and potential for unexpected behavior.