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
varare 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
varcan 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
letare scoped to the nearest enclosing block (e.g.,{}).
- Variables declared with
- Hoisting: Hoisted but not initialized.
letvariables 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
letcan 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,constvariables are scoped to the nearest enclosing block.
- Like
- Hoisting: Hoisted but not initialized.
- Similar to
let,constvariables 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
constby default for variables whose values do not change after initialization. - Use
letwhen you need to reassign the variable. - Avoid using
varin modern JavaScript due to its function-scoping and potential for unexpected behavior.
