JavaScript Variables
Variables are boxes for storing data — you label each box with a name, then put data in, take data out, or swap it anytime.
What Are Variables
Imagine a row of labeled boxes: one called "name" holds "John," another called "age" holds 25. The contents can change, but the label stays the same — that's a variable.
In JS, you create variables using declaration keywords (var / let / const) and assign values with the equals sign:
<script>
var name = "John";
let age = 25;
const PI = 3.14;
</script>
The Problems with var
var was the only way to declare variables before ES6. It has two headache-inducing behaviors:
- Function scope — a variable declared with
varinside aniforforblock is accessible outside, which is counterintuitive - Hoisting —
vardeclarations are "hoisted" to the top of their scope, but assignments are not. You can use a variable before its declaration (its value will beundefined) without errors, which leads to subtle bugs
These two behaviors make var a breeding ground for bugs. In modern JS, var has been largely replaced by let and const.
let — Block Scope, Recommended Default
let was introduced in ES6 (2015) and fixes both problems with var:
- Block scope — only accessible within
{}, cannot be accessed outside the block - No hoisting — using a variable before its declaration throws an error (temporal dead zone)
In daily development, use let for variables that need to be reassigned.
const — Constants, Cannot Be Reassigned
const also has block scope, but it must be assigned at declaration and cannot be reassigned afterward.
Note: const restricts "reassignment," not "mutation." If a const holds an object or array, you can modify object properties or array elements — you just can't point the variable to a different object.
Use const by default; switch to let when you need to reassign — this is the best practice.
Variable Naming Rules
- Must start with a letter, underscore
_, or dollar sign$ - Subsequent characters can be letters, digits, underscores, or dollar signs
- Cannot start with a digit
- Cannot use JS keywords (
var,let,function, etc.) - camelCase is recommended:
firstName,totalPrice
Declaring Multiple Variables
You can declare multiple variables at once, separated by commas:
<script>
let a = 1, b = 2, c = 3;
</script>
However, for readability, one variable per line is preferred.
Example: var Hoisting and Function Scope
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Variables - var Problems</title>
<style>
body { font-family: Arial, sans-serif; max-width: 550px; margin: 60px auto; }
.warn { background: #fff3e0; padding: 12px; border-radius: 8px; color: #E65100; border-left: 4px solid #FF9800; margin: 12px 0; }
.result { background: #f5f5f5; padding: 16px; border-radius: 8px; font-family: Consolas, monospace; line-height: 1.8; margin: 12px 0; }
button { padding: 10px 24px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; color: #fff; background: #FF9800; margin: 6px; }
button:hover { background: #F57C00; }
</style>
</head>
<body>
<h2>var Problems Demo</h2>
<p class="warn">⚠️ var has hoisting and function scope issues — avoid it in modern code</p>
<button id="hoistBtn">Demo: Hoisting</button>
<button id="scopeBtn">Demo: Scope Leakage</button>
<div class="result" id="output">Click a button to see results</div>
<script>
document.getElementById("hoistBtn").onclick = function() {
var output = "";
output += "Accessing x before var declaration: x = " + typeof x + "\n";
var x = 10;
output += "After declaration: x = " + x + "\n\n";
output += "👆 Hoisting causes no error before declaration, but value is undefined\n";
output += "This can easily cause bugs in large projects!";
document.getElementById("output").textContent = output;
};
document.getElementById("scopeBtn").onclick = function() {
var output = "";
for (var i = 0; i < 3; i++) {
// var i leaks outside the loop
}
output += "After loop, i = " + i + "\n\n";
output += "👆 var i leaked outside the loop!\n";
output += "With let i, it would not be accessible outside";
document.getElementById("output").textContent = output;
};
</script>
</body>
</html>
Example: let Block Scope
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Variables - let Block Scope</title>
<style>
body { font-family: Arial, sans-serif; max-width: 550px; margin: 60px auto; }
.good { background: #e8f5e9; padding: 12px; border-radius: 8px; color: #2E7D32; border-left: 4px solid #4CAF50; margin: 12px 0; }
.result { background: #f5f5f5; padding: 16px; border-radius: 8px; font-family: Consolas, monospace; line-height: 1.8; margin: 12px 0; }
button { padding: 10px 24px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; color: #fff; background: #4CAF50; margin: 6px; }
button:hover { background: #388E3C; }
</style>
</head>
<body>
<h2>let Block Scope Demo</h2>
<p class="good">✅ let has block scope — inaccessible outside {}, which is safer</p>
<button id="letScopeBtn">Demo: let Block Scope</button>
<button id="letLoopBtn">Demo: let in Loops</button>
<div class="result" id="output">Click a button to see results</div>
<script>
document.getElementById("letScopeBtn").onclick = function() {
let output = "Block scope test:\n";
let x = 100;
output += "Outer x = " + x + "\n";
{
let x = 200;
output += "Inner x = " + x + "\n";
}
output += "After block, x = " + x + "\n\n";
output += "👆 Inner and outer x are independent of each other";
document.getElementById("output").textContent = output;
};
document.getElementById("letLoopBtn").onclick = function() {
let output = "let in loops:\n";
for (let i = 0; i < 3; i++) {
output += "Inside loop, i = " + i + "\n";
}
output += "\n";
try {
output += "Outside loop, i = " + i;
} catch(e) {
output += "Accessing i outside loop → Error: " + e.message;
}
output += "\n\n👆 let i is confined to the loop and doesn't leak outside";
document.getElementById("output").textContent = output;
};
</script>
</body>
</html>
Example: const Constants
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Variables - const Constants</title>
<style>
body { font-family: Arial, sans-serif; max-width: 550px; margin: 60px auto; }
.tip { background: #e3f2fd; padding: 12px; border-radius: 8px; color: #1565C0; border-left: 4px solid #2196F3; margin: 12px 0; }
.result { background: #f5f5f5; padding: 16px; border-radius: 8px; font-family: Consolas, monospace; line-height: 1.8; margin: 12px 0; }
button { padding: 10px 24px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; color: #fff; margin: 6px; }
#constBtn { background: #9C27B0; }
#objectBtn { background: #2196F3; }
</style>
</head>
<body>
<h2>const Constants Demo</h2>
<p class="tip">💡 const cannot be reassigned, but object/array properties and elements can be modified</p>
<button id="constBtn">Demo: const Reassignment Error</button>
<button id="objectBtn">Demo: Modifying const Object</button>
<div class="result" id="output">Click a button to see results</div>
<script>
document.getElementById("constBtn").onclick = function() {
const PI = 3.14159;
let output = "const PI = " + PI + "\n\n";
output += "Attempting to reassign PI = 3.14:\n";
try {
PI = 3.14;
} catch(e) {
output += "❌ Error: " + e.message;
}
output += "\n\n👆 Once assigned, a const variable cannot be changed";
document.getElementById("output").textContent = output;
};
document.getElementById("objectBtn").onclick = function() {
const person = { name: "John", age: 25 };
let output = "const person = " + JSON.stringify(person) + "\n\n";
output += "Modifying person.age = 26:\n";
person.age = 26;
output += "person = " + JSON.stringify(person) + "\n\n";
output += "Adding person.city = 'New York':\n";
person.city = "New York";
output += "person = " + JSON.stringify(person) + "\n\n";
output += "👆 const locks the variable reference, not the object content\n";
output += "Like a box with a locked label — what's inside can still change";
document.getElementById("output").textContent = output;
};
</script>
</body>
</html>
Example: var / let / const Comparison
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Variables - Three Declarations Compared</title>
<style>
body { font-family: Arial, sans-serif; max-width: 600px; margin: 60px auto; }
table { width: 100%; border-collapse: collapse; margin: 16px 0; }
th, td { padding: 10px; text-align: center; border: 1px solid #ddd; }
th { background: #2196F3; color: #fff; }
.bad { color: #f44336; }
.good { color: #4CAF50; font-weight: bold; }
button { margin-top: 12px; padding: 10px 24px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; color: #fff; background: #e91e63; }
#result { margin-top: 12px; padding: 16px; background: #f5f5f5; border-radius: 8px; font-family: Consolas, monospace; line-height: 1.8; }
</style>
</head>
<body>
<h2>var / let / const Comparison</h2>
<table>
<tr><th>Feature</th><th>var</th><th>let</th><th>const</th></tr>
<tr><td>Scope</td><td class="bad">Function</td><td class="good">Block</td><td class="good">Block</td></tr>
<tr><td>Hoisting</td><td class="bad">Yes (undefined)</td><td class="good">No (TDZ)</td><td class="good">No (TDZ)</td></tr>
<tr><td>Reassignable</td><td class="bad">Yes</td><td>Yes</td><td class="bad">No</td></tr>
<tr><td>Use before declare</td><td class="bad">No error</td><td class="good">Error</td><td class="good">Error</td></tr>
<tr><td>Recommended</td><td class="bad">Avoid</td><td class="good">Recommended</td><td class="good">Preferred</td></tr>
</table>
<button id="testBtn">Run Comparison Test</button>
<div id="result"></div>
<script>
document.getElementById("testBtn").onclick = function() {
var output = "=== Comparison Test ===\n\n";
output += "[var] Function scope:\n";
for (var i = 0; i < 3; i++) {}
output += "var i outside loop = " + i + " (leaked)\n\n";
output += "[let] Block scope:\n";
for (let j = 0; j < 3; j++) {}
try {
output += "let j outside loop = " + j;
} catch(e) {
output += "Accessing let j outside loop → " + e.message + " (correct behavior)";
}
output += "\n\n[const] No reassignment:\n";
const MAX = 100;
output += "const MAX = " + MAX + "\n";
try {
MAX = 200;
} catch(e) {
output += "Reassignment → " + e.message + " (correct behavior)";
}
output += "\n\nConclusion: const > let >> var";
document.getElementById("result").textContent = output;
};
</script>
</body>
</html>
📖 Summary
- Variables are boxes for storing data, created with a declaration keyword + variable name + assignment
varhas function scope and hoisting issues — avoid it in modern JSlethas block scope and no hoisting — use it when reassignment is neededconsthas block scope and cannot be reassigned — must be assigned at declarationconstprevents reassignment, but object/array properties and elements can still be modified- Priority: const first, let second, avoid var
❓ FAQ
person to a different object, but modifying existing object properties is perfectly fine. It's like locking the label on a box (this box is always "John's box"), but you can put whatever you want inside.📝 Exercises
- Basic: Declare a constant
SITE_NAMEwith your name usingconst, and a variablevisitCountset to 0 usinglet, then display both values on the page. - Intermediate: Create a page with a button that simulates a "visit counter" — each click increments
visitCountby 1 and displays the current value. Notice howletallows reassignment whileconstdoesn't. - Challenge: Create a page with a
conststudent object{ name: "John", scores: [80, 90, 75] }. Then add a new score of 85, calculate the average, and change the name to "Jane" — all without reassigning the const, proving that object contents can be modified.



