In computer programming, a variable is a named storage location in memory used to store, retrieve, and manipulate data during program execution. In modern JavaScript, variable management underwent a monumental transformation with the introduction of ES6 (ECMAScript 2015), replacing the fragile legacy var keyword with robust block-scoped let and const.
JavaScript provides three keywords to declare variables. Choosing the correct keyword is fundamental to software reliability and memory hygiene:
| Feature | var (Legacy ES5) |
let (Modern ES6+) |
const (Modern ES6+) |
|---|---|---|---|
| Scope Model | Function Scoped (Ignores blocks!) | Block Scoped ({ ... }) |
Block Scoped ({ ... }) |
| Reassignment | Allowed (x = 20) |
Allowed (x = 20) |
Forbidden (TypeError) |
| Re-declaration | Allowed in same scope (Bug-prone) | Forbidden (SyntaxError) | Forbidden (SyntaxError) |
| Hoisting Behavior | Hoisted with undefined |
Hoisted into TDZ | Hoisted into TDZ |
| Global Object Attachment | Attaches to window.varName |
Does not attach to window | Does not attach to window |
A block is any code enclosed within curly braces { ... } (e.g., inside if statements, for loops, or functions). let and const respect block boundaries, whereas var brazenly leaks out into the surrounding function or global scope:
// 1. Demonstrating var leakage
if (true) {
var leakedVar = "I escaped the if-block!";
let scopedLet = "I am trapped inside!";
}
console.log(leakedVar); // Works! Output: "I escaped the if-block!"
// console.log(scopedLet); // ReferenceError: scopedLet is not defined
// 2. Loop variable bug with var vs. let
for (var i = 0; i < 3; i++) {
// With var, 'i' is shared globally across all iterations
}
console.log("Final i with var:", i); // Output: 3 (Pollutes outer scope!)
for (let j = 0; j < 3; j++) {
// With let, a fresh 'j' binding is created per iteration
}
// console.log(j); // ReferenceError: j is not defined (Safe & Clean!)
All variable declarations in JavaScript are technically hoisted (recognized by the engine during the compile/memory creation phase). However, they behave completely differently during execution:
var is initialized with undefined immediately upon hoisting.let and const remain uninitialized in the Temporal Dead Zone (TDZ) from the moment the block is entered until the actual declaration statement is executed.// Hoisting with var:
console.log(myVar); // Output: undefined (No crash, but misleading)
var myVar = 100;
// Hoisting with let / const (TDZ):
// console.log(myLet); // CRASH! ReferenceError: Cannot access 'myLet' before initialization
let myLet = 200; // TDZ ends here for myLet
console.log(myLet); // Output: 200
A frequent source of beginner confusion is assuming that const makes an object immutable. In JavaScript, const creates an immutable variable identifier binding, meaning you cannot reassign the variable to a different value or reference. However, the properties inside the object or elements inside the array can still be modified:
const student = {
name: "Vikram",
rollNumber: 104
};
// 1. Mutating properties is 100% VALID:
student.name = "Vikram Aditya"; // Allowed!
student.gpa = 3.9; // Allowed!
console.log(student); // { name: "Vikram Aditya", rollNumber: 104, gpa: 3.9 }
// 2. Reassigning the variable throws an Error:
// student = { name: "New Student" }; // TypeError: Assignment to constant variable!
// To truly freeze an object against mutations:
Object.freeze(student);
student.name = "Cannot Change"; // Silently fails or throws in strict mode
Exam Question: "State the Golden Rule of Variable Declaration in Modern JavaScript."
The Industry Golden Rule:
1. Default to const for 90%+ of all declarations (variables, functions, objects, arrays, imported modules).
2. Use let ONLY when you explicitly expect the variable's value to be reassigned (e.g., loop counters, accumulators).
3. NEVER use var in modern ECMAScript development.
Now that you master variable scoping and bindings, let us explore the data type taxonomy and memory storage mechanisms of JavaScript. Proceed to: JavaScript Data Types & Memory Allocation →
Accelerate your JavaScript mastery by studying these tightly connected core tutorials:
Primitive values vs Reference objects.
Memory allocation phase and TDZ details.
Lexical scoping and block scopes.
Implicit coercion and explicit casting.