JavaScript has three main ways to declare variables:
varletconstThey all declare variables, but they behave differently in scope, hoisting, and reassignment.
varvar is the oldest declaration style in JavaScript, and it has several well-known problems.
var is function-scoped, not block-scoped.
if (true) { var x = 10;}
console.log(x); // 10var declarations are hoisted to the top of their function or global scope.
console.log(a); // undefinedvar a = 5;JavaScript treats that roughly like:
var a;console.log(a);a = 5;var allows redeclaration:
var name = "Tom";var name = "Alice";letlet was introduced in ES6 and fixes many of var’s problems.
if (true) { let x = 10;}
// console.log(x); // ReferenceErrorlet is hoisted, but it cannot be used before the declaration line.
// console.log(a); // ReferenceErrorlet a = 5;let value = 1;// let value = 2; // SyntaxErrorconstconst has the same block scope rules as let, but adds stronger assignment rules.
const pi = 3.14;const name = "Tom";// name = "Alice"; // TypeErrorconst prevents reassignment of the variable binding, but it does not make the object or array itself immutable.
const user = { name: "Tom" };user.name = "Alice"; // allowed
const arr = [1, 2, 3];arr.push(4); // allowedconst by defaultlet if reassignment is necessaryvar unless you are maintaining old codeThis rule keeps code easier to read and reduces accidental state changes.
| Declaration | Scope | Hoisting behavior | Redeclaration | Reassignment |
|---|---|---|---|---|
var | Function scope | Hoisted and initialized to undefined | Allowed | Allowed |
let | Block scope | Hoisted but in TDZ | Not allowed | Allowed |
const | Block scope | Hoisted but in TDZ | Not allowed | Not allowed |
Using var in a loop often causes closure issues because all callbacks share the same variable.
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0);}
// 3// 3// 3With let, each loop iteration gets its own binding:
for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0);}
// 0// 1// 2In modern JavaScript, correct use of let and const makes code safer and more predictable.