⚡ Phase 1 · Foundations
🟡 Intermediate
MODULE 05
Conditional Statements
Your progress in Phase 135%
🎯 What you'll learn: How to make decisions with if/else, switch statements, ternary operator, truthy/falsy values, short-circuit evaluation, guard clauses, and build real-world condition-based programs.
Section 1
if / else if / else
Conditionals let your code make decisions based on whether something is true or false.
if-else.js
JS
const age = 20; if (age >= 18) { console.log("You are an adult."); } else if (age >= 13) { console.log("You are a teenager."); } else { console.log("You are a child."); } // Output: "You are an adult." // Multiple conditions const hour = 14; // 2 PM if (hour < 12) { console.log("Good morning!"); } else if (hour < 17) { console.log("Good afternoon!"); } else if (hour < 21) { console.log("Good evening!"); } else { console.log("Good night!"); }
✨
Only the first TRUE branch executes
else if lets you check multiple conditions. Only the first TRUE branch executes — the rest are skipped entirely, even if they would also be true.Section 2
switch Statement
switch is cleaner when you're comparing ONE variable against MANY specific values.
switch.js
JS
const day = "Monday"; switch(day) { case "Monday": case "Tuesday": case "Wednesday": case "Thursday": case "Friday": console.log("Weekday — time to code!"); break; case "Saturday": case "Sunday": console.log("Weekend — still code but chill!"); break; default: console.log("Invalid day"); } // Another example: HTTP status codes const statusCode = 404; switch(statusCode) { case 200: console.log("OK"); break; case 301: console.log("Moved Permanently"); break; case 404: console.log("Not Found"); break; case 500: console.log("Server Error"); break; default: console.log("Unknown status"); }
⚠️
Always use break; to prevent fall-through
ALWAYS use
break; at the end of each case (unless you intentionally want "fall-through"). Forgetting break is one of the most common switch bugs!Section 3
Truthy and Falsy Values
In JavaScript, every value is either "truthy" (behaves like true) or "falsy" (behaves like false) when used in a condition.
The 7 (actually 8) Falsy Values
falsy-values.js
JS
// The falsy values in JavaScript: if (false) console.log("falsy"); // 1. false if (0) console.log("falsy"); // 2. 0 if (-0) console.log("falsy"); // 3. -0 if (0n) console.log("falsy"); // 4. BigInt 0 if ("") console.log("falsy"); // 5. empty string if (null) console.log("falsy"); // 6. null if (undefined) console.log("falsy"); // 7. undefined if (NaN) console.log("falsy"); // 8. NaN // EVERYTHING ELSE is truthy: if (1) console.log("truthy"); // any non-zero number if ("0") console.log("truthy"); // non-empty string (even "0"!) if ([]) console.log("truthy"); // empty array is TRUTHY! if ({}) console.log("truthy"); // empty object is TRUTHY! if ("false") console.log("truthy"); // non-empty string
⚠️
Common trap: [] and {} are truthy!
An empty array
[] and empty object {} are TRUTHY in JavaScript. Only "" (empty string) is falsy — not empty array or object. This surprises many developers!Practical Truthy/Falsy Usage
truthy-practical.js
JS
// Check if string is not empty const username = "Alice"; if (username) { console.log(`Hello, ${username}!`); } else { console.log("Please enter a username"); } // Check if array has items const items = [1, 2, 3]; if (items.length) { console.log(`You have ${items.length} items`); }
Section 4
Short-Circuit Evaluation
JavaScript's && and || operators don't just return true or false — they return the actual value at which evaluation stops.
short-circuit.js
JS
// && stops at first falsy const user = null; const name = user && user.name; // null (short-circuits at user) console.log(name); // null // || stops at first truthy const displayName = "" || "Anonymous"; console.log(displayName); // "Anonymous" // Practical: conditional function call const logError = (err) => console.error(err); const error = "Something went wrong"; error && logError(error); // only calls if error is truthy // Guard pattern function greet(name) { name || (name = "Stranger"); // same as: if (!name) name = "Stranger" return `Hello, ${name}!`; } console.log(greet("")); // "Hello, Stranger!" console.log(greet("Alice")); // "Hello, Alice!"
Section 5
Guard Clauses Pattern
Guard clauses return early from a function when conditions aren't met — this keeps code flat and readable.
guard-clauses.js
JS
// WITHOUT guard clauses (nested, hard to read) function processOrder(order) { if (order) { if (order.items) { if (order.items.length > 0) { if (order.user) { console.log("Processing order..."); } } } } } // WITH guard clauses (flat, clean, readable) function processOrder2(order) { if (!order) return console.log("No order"); if (!order.items) return console.log("No items"); if (order.items.length === 0) return console.log("Empty cart"); if (!order.user) return console.log("Not logged in"); console.log("Processing order..."); // only reached if ALL checks pass }
✨
Guard clauses are a professional pattern
Guard clauses (early returns) reduce nesting, make code easier to read, and clarify exactly what conditions must be true. Senior developers use this pattern constantly.
Section 6
Real-World Examples
Age Validator
age-validator.js
JS
function validateAge(age) { if (typeof age !== "number") return "Invalid: not a number"; if (age < 0) return "Invalid: negative age"; if (age > 120) return "Invalid: unrealistic age"; if (age < 18) return "Minor — restricted access"; if (age >= 65) return "Senior — apply discounts"; return "Adult — full access granted"; } console.log(validateAge(25)); // "Adult — full access granted" console.log(validateAge(14)); // "Minor — restricted access" console.log(validateAge(-5)); // "Invalid: negative age"
Grade System
grade-system.js
JS
function getGrade(score) { if (score < 0 || score > 100) return "Invalid score"; if (score >= 90) return "A — Excellent!"; if (score >= 80) return "B — Good"; if (score >= 70) return "C — Average"; if (score >= 60) return "D — Below Average"; return "F — Fail"; } console.log(getGrade(95)); // "A — Excellent!" console.log(getGrade(72)); // "C — Average" console.log(getGrade(55)); // "F — Fail"
Login Checker
login-checker.js
JS
const credentials = { username: "admin", password: "secret123", isActive: true }; function login(username, password) { // Guard clauses if (!username || !password) return "Missing credentials"; if (username !== credentials.username) return "User not found"; if (password !== credentials.password) return "Wrong password"; if (!credentials.isActive) return "Account deactivated"; return `Welcome back, ${username}!`; } console.log(login("admin", "secret123")); // "Welcome back, admin!" console.log(login("admin", "wrong")); // "Wrong password" console.log(login("", "pass")); // "Missing credentials"
Section 7
Nested Conditions — and When to Avoid
nested-refactor.js
JS
// Deeply nested — hard to read (code smell) function checkAccess(user, resource) { if (user) { if (user.isLoggedIn) { if (user.role === "admin") { if (resource.exists) { return true; } } } } return false; } // Refactored with guard clauses + combined && conditions function checkAccess2(user, resource) { if (!user || !user.isLoggedIn) return false; if (user.role !== "admin") return false; if (!resource.exists) return false; return true; }
✨
Deeply nested if = code smell
Deeply nested if statements are a code smell. Refactor with guard clauses, combine conditions with
&&/||, or use switch. Your future self (and teammates) will thank you.Section 8
Lesson Summary
✅if / else if / else — chain conditions, only the first TRUE branch runs.
✅switch — clean way to compare one value against many; always use
break.✅Truthy/Falsy — 8 falsy values; everything else is truthy.
[] and {} are truthy!✅Short-circuit —
&& stops at first falsy, || stops at first truthy.✅Guard clauses — early returns flatten nesting and make code more readable.
✅Avoid deeply nested conditionals — combine with
&&/|| or refactor to guards.🧩 Knowledge Check — Lesson 5
Answer all 5 questions to test your understanding. Instant feedback on every answer.
1. Which of the following values is TRUTHY in JavaScript?
2. What happens if you forget
break in a switch case?3. What is a guard clause?
4. What does
if (username) check when username is an empty string?5. How do you check if BOTH conditions must be true?
Coding Challenge — Lesson 5
Apply what you learned · Intermediate Level
Build a real BMI calculator that uses all the conditional patterns from this lesson.
Challenge: Build a BMI Calculator with Conditions
Create a file called
Create a file called
bmiCalc.js. Write a function calculateBMI(weight, height) where weight is in kg and height is in meters.
- Formula: BMI = weight / (height * height)
- Under 18.5: "Underweight"
- 18.5 to 24.9: "Normal weight"
- 25 to 29.9: "Overweight"
- 30 or above: "Obese"
- Add guard clauses for: invalid inputs (negative/zero), missing values
- Log:
"Your BMI is X.XX — Category" - Test with at least 4 different inputs
💡 Show hints if you're stuck
- Use
toFixed(2)for rounding:bmi.toFixed(2) - Use guard clauses at the start:
if (!weight || !height) return "Missing values"; - Use an
else ifchain for categories after computing BMI - Remember: BMI is weight/(height²) — not weight/height
- Test: 70kg, 1.75m → BMI ~22.9 → "Normal weight"
Finished this lesson?
Mark it complete to track your progress.
Module 05 of 07
Phase 1 — JS Foundations