A variable is a named container in memory used to store data during program execution. This data can be accessed or modified later in the script.
"In JavaScript, variables are used to store values like strings, numbers, objects, functions, etc., and they allow the program to dynamically interact with and manipulate data."
- Think of a variable as a label stuck on a box where you can put any kind of value — and possibly change it later.
- JavaScript is dynamically typed, so a variable can store any data type without specifying it beforehand.
JavaScript has three ways to declare a variable, depending on the version:
| Version | Keyword |
|---|---|
| ES5 | var |
| ES6 | let, const |
- ES6 introduced
letandconstto solve the problems caused byvar, such as hoisting and re-declaration. - Using
varis discouraged in modern JavaScript because of scoping issues and lack of predictability.
Use let and const in all new code:
letfor variables you expect to changeconstfor values that must remain constant- Avoid
varentirely unless dealing with old codebases
var user = "Alice"; // ES5
let count = 5; // ES6
const PI = 3.14; // ES6All of these create variables. The difference lies in how they behave in terms of scope, re-declaration, and mutability.
| Keyword | Declaration | Initialization | Re-initialization | Re-declaration |
|---|---|---|---|---|
var |
✅ | ✅ | ✅ | ✅ |
let |
✅ | ✅ | ✅ | ❌ |
const |
✅ | ✅ (must) | ❌ | ❌ |
"The
letandconstkeywords introduced in ES6 provide better scoping rules and prevent bugs caused by variable re-declaration.constenforces immutability, though objects declared withconstcan still be mutated."
- Use
constby default, unless you need to change the value later, then uselet. varcan lead to accidental re-declarations and hard-to-debug hoisting issues.- Using
let/consthelps with cleaner, predictable code.
| Keyword | Scope |
|---|---|
var |
Function-scoped |
let |
Block-scoped |
const |
Block-scoped |
"
varignores block boundaries likeifandforblocks, whileletandconstrespect them, reducing the chance of variable collisions or logic errors."
if (true) {
var x = 10;
}
console.log(x); // 10 ✅ (due to function scoping)
if (true) {
let y = 20;
}
console.log(y); // ❌ ReferenceError (block scoped)var userName = "John";
userName = "Johnny"; // ✅ allowed
var userName = "JD"; // ✅ allowedvarallows both re-initialization and re-declaration.- But that’s risky — could accidentally override variables.
let age = 25;
age = 26; // ✅ allowed
let age = 27; // ❌ Error: already declaredletallows re-initialization but not re-declaration in the same scope.- Safer than
var.
const country = "India";
country = "USA"; // ❌ Error: cannot reassign
const country = "UK"; // ❌ Error: already declaredconstmust be initialized at declaration and cannot be reassigned.- Use for values that should never change.
const x; // ❌ SyntaxError: Missing initializer
console.log(x);✅ Correct:
const x = 10;
console.log(x); // 10const user = { name: "Arun" };
user.name = "John"; // ✅ Allowed (object mutated)
user = { name: "Alex" }; // ❌ Error: cannot reassign the variable💡
constprevents reassignment, but doesn't make objects immutable.
Use Object.freeze() for deep immutability if required.
| Use Case | Keyword |
|---|---|
| Value won't change | const |
| Value might change | let |
| Legacy or old JS codebases | var |
- Prefer
letandconstovervar - Use
constunless mutation is needed - Understand scoping differences and hoisting behavior
- Know how re-declaration and re-assignment differ
- Enable strict mode (
"use strict") to catch silent errors - Use block scope to reduce global variable pollution
- Avoid using
varunless specifically required
“In modern JavaScript,
letandconstreplacedvarto provide block-scoping and prevent issues like re-declaration and hoisting. Useconstby default and switch toletonly when you need to reassign. Avoidvarfor cleaner and more maintainable code.”
Hoisting is JavaScript’s default behavior of moving variable and function declarations to the top of their scope before code execution.
- Only declarations are hoisted—not initializations.
- Applies to
var,let,const, and functions (in different ways).
console.log(x); // Output: undefined (not error!)
var x = 10;Internally:
var x; // hoisted declaration
console.log(x); // undefined
x = 10;✅ Why undefined? → Because declaration is hoisted, but not the assignment.
console.log(y); // ❌ ReferenceError: Cannot access 'y' before initialization
let y = 20;console.log(z); // ❌ ReferenceError: Cannot access 'z' before initialization
const z = 30;Even though
letandconstare hoisted, they are in a Temporal Dead Zone (TDZ) from the start of their block until their declaration is executed.
| Keyword | Hoisted | Can Access Before Declaration? | Behavior |
|---|---|---|---|
var |
Yes | Yes | undefined, due to hoisting |
let |
Yes | ❌ No | ReferenceError (TDZ) |
const |
Yes | ❌ No | ReferenceError (TDZ) |
"In JavaScript, variables declared using
varare hoisted and initialized withundefined, whereasletandconstare hoisted too, but remain in the Temporal Dead Zone until they are initialized, causing a ReferenceError if accessed early."
The TDZ is the time between the entering of the scope and the actual declaration line of the variable. During this time:
- The variable is in scope.
- But cannot be accessed.
- Any attempt will throw a ReferenceError.
{
// TDZ starts here for `score`
// console.log(score); // ❌ ReferenceError
let score = 100; // TDZ ends here
console.log(score); // ✅ 100
}- Declared outside any block or function.
- Accessible from anywhere in the code.
- Declared inside a function or block.
- Only accessible within that block.
let globalVar = "I’m global";
function testScope() {
let localVar = "I’m local";
console.log(globalVar); // ✅ Accessible
console.log(localVar); // ✅ Accessible
}
console.log(globalVar); // ✅
console.log(localVar); // ❌ Error| Keyword | Scope Type |
|---|---|
var |
Function Scope |
let |
Block Scope |
const |
Block Scope |
if (true) {
var a = 10;
let b = 20;
const c = 30;
}
console.log(a); // ✅ 10 (function-scoped)
console.log(b); // ❌ ReferenceError (block-scoped)
console.log(c); // ❌ ReferenceError (block-scoped)When a variable in a local scope has the same name as one in the outer scope.
let x = "outer";
function shadow() {
let x = "inner";
console.log(x); // inner (shadows outer x)
}
shadow();
console.log(x); // outer- Can re-declare and re-assign
- Can re-assign, cannot re-declare in the same scope
- Cannot re-assign or re-declare
| Practice | Why? |
|---|---|
Prefer const by default |
Prevents accidental reassignments |
Use let when value will change |
Ideal for counters, loops, etc. |
Avoid var |
Due to function scope and hoisting pitfalls |
| Declare variables near their usage | Improves readability and reduces bugs |
| Use meaningful variable names | For better code clarity |