JavaScript Roadmap — Day 3: Variables — var, let, and const

 

JavaScript · Day 3 of 180 · Beginner Phase

Variables — var, let, and const

Variables are containers that store data. Choosing the right one — var, let, or const — is the foundation of writing clean, bug-free JavaScript.

Day 3 / 180
Beginner Phase

Look at this code. A developer wrote it in 2015 — and it has a hidden bug that took 3 hours to find:

JavaScript — Can you find the bug?
var isLoggedIn = true;

if(isLoggedIn) {
  var userName = "Waheed"; // declared inside if block
}

console.log(userName); // "Waheed" — works... but should it?

// Later in the code — someone changes isLoggedIn
isLoggedIn = false;
// userName still exists and still has a value!
// var leaked OUT of the if block — this is the bug

The problem:

var does not respect block boundaries — it leaks out of if blocks, for loops, and any other {}. This causes variables to exist in places they should not — leading to subtle, hard-to-find bugs. The fix is simple: use let instead. This is exactly why let and const were added to JavaScript in 2015.

Every program needs to store data — names, numbers, scores, prices. In JavaScript we use variables to store this data. There are three ways to create them. Choosing the right one is not just style — it is the difference between code that works correctly and code that has hidden bugs.

Feature var let const
Scope Function scope Block scope Block scope
Reassign ✅ Yes ✅ Yes ❌ No
Redeclare ✅ Yes ❌ No ❌ No
Hoisting Yes (undefined) Yes (TDZ) Yes (TDZ)
Use today? ❌ Avoid ✅ Yes ✅ Prefer

1. What is a Variable?

A variable is a named container that holds a value. Think of it like a labeled box — you put data inside, give it a name, and use that name to find the data later. Without variables you would have to type the same values over and over everywhere in your code.

JavaScript — Variables basics
// Three ways to declare variables
var   name    = "Waheed";    // old — avoid in modern code
let   age     = 22;          // modern — value can change
const country = "Pakistan";  // constant — value cannot change

console.log(name);    // Waheed
console.log(age);     // 22
console.log(country); // Pakistan

// Without variables — imagine repeating this everywhere
console.log("Welcome, Waheed from Pakistan!");
console.log("Hello again, Waheed!");
console.log("Waheed's profile");

// With variables — change once, updates everywhere
const user = "Waheed";
console.log(`Welcome, ${user}!`);
console.log(`Hello again, ${user}!`);
console.log(`${user}'s profile`);

💡 Naming rules: Variable names must start with a letter, $, or _. They cannot start with a number. Use camelCasemyVariableName not my_variable_name. Names are case-sensitive — score and Score are two completely different variables.

2. let — The Modern Variable

let was introduced in ES6 (2015) to fix the problems with var. Use let when the value will change — like a counter, a score, a user's current selection, or anything that gets updated during the program.

JavaScript — let in depth
// let can be reassigned
let score = 0;
score = 10;   // ✅ OK
score = 25;   // ✅ OK again
console.log(score); // 25

// let CANNOT be redeclared in same scope
let city = "Lahore";
// let city = "Karachi"; // ❌ SyntaxError — already declared

// let is BLOCK SCOPED — only lives inside {}
{
  let x = 100;
  console.log(x); // 100 — works inside block
}
// console.log(x); // ❌ ReferenceError — x does not exist here

// Real world example — counter
let likes = 0;
likes++;  // user clicked like
likes++;  // another user liked
console.log(`Total likes: ${likes}`); // Total likes: 2

3. const — The Constant

const declares a variable that cannot be reassigned. Use it for values that should never change — API keys, configuration, mathematical constants, or any value you want to protect from accidental change. In modern JavaScript const is the default choice — use it unless you know the value will change.

JavaScript — const in depth
// const cannot be reassigned
const PI      = 3.14159;
const API_URL  = "https://api.waheedblog.online";
const siteName = "WaheedBlog";

// PI = 3.14; // ❌ TypeError: Assignment to constant variable

// IMPORTANT — const with objects
// const does NOT mean the object is frozen
const user = { name: "Waheed", age: 22 };

user.age = 23;       // ✅ OK — changing a property
user.city = "Lahore"; // ✅ OK — adding a property
console.log(user);    // { name: "Waheed", age: 23, city: "Lahore" }

// user = {}; // ❌ Error — cannot reassign the variable itself

// Same with arrays
const colors = ["red", "blue"];
colors.push("green"); // ✅ OK — modifying the array
console.log(colors);  // ["red", "blue", "green"]
// colors = []; // ❌ Error — cannot reassign

🔥 The most important thing about const: const prevents you from reassigning the variable — not from changing the contents of an object or array. This surprises almost every beginner. const locks the box — but you can still change what is inside the box. Only the label is permanent.

4. var — Why You Should Avoid It

var was the only way to declare variables before ES6. It works — but it has three behaviors that cause real bugs. Every modern JavaScript codebase has moved away from var. You need to understand it because you will see it in old code — but never use it in new code.

JavaScript — Three problems with var
// Problem 1 — var leaks out of blocks
{
  var leaked = 10;
}
console.log(leaked); // 10 — leaked outside! (let would error)

for(var i = 0; i < 3; i++) {}
console.log(i); // 3 — i leaked from the loop!

// Problem 2 — var can be redeclared silently
var userName = "Waheed";
var userName = "Ali";    // No error! Silently overwrites
console.log(userName); // Ali — original value gone

// Problem 3 — var hoisting gives undefined (not an error)
console.log(myVar); // undefined — no error but wrong!
var myVar = "hello";
// With let this would throw: ReferenceError
// Which is actually BETTER — it tells you something is wrong

5. Scope Deep Dive — Where Variables Live 🔥

Scope is the region of your code where a variable exists and can be accessed. Understanding scope is one of the most important concepts in JavaScript — it explains why variables sometimes seem to disappear or cause unexpected errors.

JavaScript — Scope explained
// GLOBAL SCOPE — accessible everywhere
const siteName = "WaheedBlog";

function greet() {
  // FUNCTION SCOPE — local to this function
  const message = "Hello!";
  console.log(siteName); // ✅ Can access global
  console.log(message);  // ✅ Can access local
}

greet();
// console.log(message); // ❌ ReferenceError — message is local

// BLOCK SCOPE — let and const only live inside {}
if(true) {
  let blockVar = "I am block scoped";
  const alsoBlock = "Me too";
  console.log(blockVar);  // ✅ Works
}
// console.log(blockVar); // ❌ ReferenceError

// SCOPE CHAIN — inner can see outer, outer cannot see inner
const outer = "I am outer";
{
  const inner = "I am inner";
  console.log(outer); // ✅ Inner can see outer
  console.log(inner); // ✅ Inner can see itself
}
// console.log(inner); // ❌ Outer cannot see inner
Pro Tip #1 — Use const by default
Start every variable with const. Only change to let if you get an error saying you cannot reassign. This habit makes your code safer, more readable, and tells other developers that this value is intentionally fixed. Never start with var.
Pro Tip #2 — Descriptive names save hours
Name your variables to describe exactly what they hold. userAge is infinitely better than x. isLoggedIn is better than flag. totalCartPrice is better than total. You will read your code far more than you write it — name things for the reader, not the writer.
Pro Tip #3 — const does not freeze objects
const prevents reassignment of the variable — but object properties and array elements can still change. If you truly need an immutable object use Object.freeze(obj). This is an advanced pattern but good to know exists for when you need it.

6. Hoisting — The Hidden Behavior

Hoisting is JavaScript's behavior of moving variable and function declarations to the top of their scope before code runs. It sounds confusing but understanding it explains some very common bugs — especially with var.

JavaScript — Hoisting behavior
// var is hoisted — but only declaration, not value
console.log(myVar); // undefined — no error, but not "hello"!
var myVar = "hello";
console.log(myVar); // "hello"

// JavaScript actually runs this as:
var myVar;           // declaration hoisted to top
console.log(myVar); // undefined
myVar = "hello";    // assignment stays in place

// let and const have Temporal Dead Zone (TDZ)
// They are hoisted but cannot be accessed before declaration
// console.log(myLet); // ❌ ReferenceError: Cannot access before init
let myLet = "hello";
console.log(myLet); // "hello" — works after declaration

// Function declarations ARE fully hoisted
greet(); // ✅ Works — called before declaration!
function greet() {
  console.log("Hello from hoisted function!");
}

7. Try It Yourself

Edit the code and click Run Code. Try uncommenting the error lines to see what happens. Experiment with scope by moving variables inside and outside blocks.

✏️ Try it Yourself — var, let, const
OUTPUT
// Click Run Code to see output
💡 Code edit karo aur Run dabao!

8. Practice Tasks

Task 1 — Easy: Declare All Three

Declare one variable with var, one with let, one with const. Try reassigning each one. Observe which one throws an error. Write a comment next to each explaining when you would use it in real code.

Task 2 — Medium: Block Scope Test

Create a block using {}. Inside it declare a variable with let and another with var. Try accessing both outside the block. Notice that let throws a ReferenceError but var does not — write a comment explaining why this is actually a feature, not a bug.

Task 3 — Hard: Your Profile with const and Object.freeze

Create a const profile object with your name, age, city, and isStudent. First try modifying a property — it should work. Then wrap it with Object.freeze(profile) and try modifying again — what happens now? Log the profile before and after. This is how you create truly immutable data in JavaScript.

Next Lesson
Day 4 — Data Types: String, Number, Boolean
Read Next Lesson →
Want daily web dev tips?
Follow Muhammad Waheed Asghar for daily JavaScript and CSS tips!

Popular Posts