What is a Variable?
A variable is a named container for storing data. Think of it as a labeled box โ you put something in, give it a name, and later you can refer to that name to get the value back (or change it).
JavaScript has three keywords for declaring variables: var, let, and const. They behave differently in important ways. Understanding these differences is foundational โ confusing them leads to real bugs.
// Three ways to declare variables
var oldWay = "I'm from the old days";
let modernWay = "I'm the modern choice";
const constant = "I cannot be reassigned";
// Basic usage
let userName = "Alice";
let userAge = 30;
let isLoggedIn = true;
console.log(userName); // Alice
console.log(userAge); // 30
console.log(isLoggedIn); // true
const โ Use This by Default
const declares a variable that cannot be reassigned. It must be initialized when declared. This is your default choice โ use const unless you know the value needs to change.
const PI = 3.14159;
const API_URL = "https://api.example.com";
const MAX_RETRIES = 3;
// This will throw an error:
// PI = 3.14; // TypeError: Assignment to constant variable
// IMPORTANT: const prevents reassignment, not mutation
const user = { name: "Alice", age: 30 };
user.name = "Bob"; // โ
This works! We're mutating, not reassigning
user.age = 25; // โ
Also fine
// user = { name: "Charlie" }; // โ This fails โ that's reassignment
const numbers = [1, 2, 3];
numbers.push(4); // โ
Works โ mutating the array
numbers[0] = 99; // โ
Works โ modifying an element
// numbers = [5, 6, 7]; // โ Fails โ reassignment
Start with const for everything. Change it to let only when you find you need to reassign it. You'll be surprised how rarely you need let.
let โ When Values Change
let allows reassignment. Use it for counters, accumulators, values that genuinely change over time.
let counter = 0;
counter++; // counter is now 1
counter += 10; // counter is now 11
counter = 0; // reset โ this works!
let message = "Hello";
message = "Goodbye"; // reassignment is allowed
// Classic use cases for let:
let score = 0;
for (let i = 0; i < 5; i++) {
score += i;
}
console.log(score); // 10
// Loop variable (must be let, not const โ it changes)
for (let i = 0; i < 3; i++) {
console.log(i); // 0, 1, 2
}
// User input that changes
let currentUser = null;
// ... later ...
currentUser = { id: 1, name: "Alice" };
// ... later still ...
currentUser = null; // logged out
Block Scope
Both let and const are block-scoped โ they only exist within the nearest set of curly braces {}:
if (true) {
let blockVariable = "I'm inside the block";
const alsoBlock = "Me too";
console.log(blockVariable); // โ
works here
}
// console.log(blockVariable); // โ ReferenceError: not defined
// Practical implication:
for (let i = 0; i < 3; i++) {
let squared = i * i;
}
// console.log(squared); // โ ReferenceError โ not accessible here
var โ The Legacy Keyword
var is the original way to declare variables. It behaves differently โ and those differences are the source of many historical JavaScript bugs. You'll see it in older code, so you need to understand it, but never use it in new code.
// var is FUNCTION-scoped (not block-scoped!)
function showVarScope() {
if (true) {
var leakyVariable = "I escape the block!";
}
console.log(leakyVariable); // โ
Accessible! This is the problem
}
showVarScope();
// The same with let:
function showLetScope() {
if (true) {
let safeVariable = "I stay in the block";
}
// console.log(safeVariable); // โ ReferenceError โ proper behavior
}
// var also allows re-declaration:
var x = 1;
var x = 2; // No error! Just silently overwrites
console.log(x); // 2
let y = 1;
// let y = 2; // SyntaxError: already been declared
Hoisting โ The Weirdest var Behavior
Variable declarations with var are "hoisted" to the top of their function. This means you can use a variable before you declare it (it just has value undefined):
// What you write:
console.log(hoisted); // undefined (not an error!)
var hoisted = "value";
console.log(hoisted); // "value"
// What JS actually does (conceptually):
var hoisted; // declaration hoisted to top
console.log(hoisted); // undefined
hoisted = "value"; // assignment stays in place
console.log(hoisted); // "value"
// let and const are different โ they're in the "temporal dead zone"
// console.log(notHoisted); // ReferenceError
let notHoisted = "value";
Naming Variables
JavaScript uses camelCase by convention. Variable names must start with a letter, underscore (_), or dollar sign ($). They're case-sensitive.
// โ
Valid names
let myVariable = 1;
let _privateVar = 2;
let $jqueryStyle = 3;
let camelCaseIsStandard = 4;
let SCREAMING_SNAKE_CASE = 5; // for constants by convention
// โ
Descriptive names (always preferred)
let userEmailAddress = "alice@example.com";
let maxRetryAttempts = 3;
let isUserAuthenticated = true;
// โ Bad names (technically valid, but confusing)
let x = "alice@example.com";
let a = 3;
let flag = true;
// โ Invalid names
// let 1stPlace = 1; // can't start with number
// let my-var = 1; // hyphens not allowed
// let let = 1; // reserved keyword
// Reserved words you can't use:
// break, case, catch, class, const, continue, debugger,
// default, delete, do, else, export, extends, finally,
// for, function, if, import, in, instanceof, let, new,
// return, static, super, switch, this, throw, try,
// typeof, var, void, while, with, yield
Comparison Summary
| Feature | var | let | const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Hoisting | Yes (undefined) | TDZ error | TDZ error |
| Re-declaration | โ Allowed | โ Error | โ Error |
| Reassignment | โ Allowed | โ Allowed | โ Error |
| Use in new code | โ Never | โ When needed | โ Default |
โก Key Takeaways
- Use
constby default โ it prevents accidental reassignment - Use
letonly when you need to reassign (counters, loops, conditional values) - Never use
varin modern JavaScript โ its scoping rules cause bugs constprevents reassignment but not mutation of objects/arrays- Both
letandconstare block-scoped โ they die at the closing} - Name variables descriptively with camelCase
๐ฏ Practice Exercises
EXERCISE 1
Declare a const object representing a product: { name, price, inStock }. Then update the price and stock status. Notice you can mutate but can't reassign.
EXERCISE 2
Write a loop using let that prints numbers 1-10 and their squares. Can you do the same with const? Why or why not?
EXERCISE 3 โ CHALLENGE
Create a variable for each: your name, age, whether you're a developer, an array of 3 hobbies, and an object with your address. Choose const vs let deliberately and justify each choice.