Making Decisions with if/else
Programs need to make decisions. The if statement is the most fundamental decision-making tool. It evaluates a condition and executes code based on whether that condition is truthy or falsy.
// Basic if statement
let temperature = 25;
if (temperature > 30) {
console.log("It's hot!");
}
// Output: nothing — condition is false
// if/else
if (temperature > 30) {
console.log("It's hot!");
} else {
console.log("It's comfortable.");
}
// Output: "It's comfortable."
// if/else if/else — multiple conditions
if (temperature > 35) {
console.log("Extreme heat warning!");
} else if (temperature > 28) {
console.log("It's hot.");
} else if (temperature > 20) {
console.log("Nice weather!");
} else if (temperature > 10) {
console.log("A bit chilly.");
} else {
console.log("Bundle up!");
}
Comparison Deep Dive
// Always use strict equality ===
let age = "25"; // string from user input
age === 25; // false — different types (string vs number)
age == 25; // true — loose equality coerces "25" to 25
// This is why == causes bugs:
"" == false; // true — surprising!
0 == false; // true — surprising!
null == undefined; // true — sometimes useful
// Real-world gotcha — form inputs return strings:
const form = { age: "25" };
if (form.age > 17) { // works because > coerces
console.log("Adult");
}
// Better — explicitly convert:
if (parseInt(form.age) >= 18) {
console.log("Adult");
}
// Comparing objects — always false (different references)
{} === {}; // false (different objects in memory)
[] === []; // false (different arrays in memory)
const a = [1,2,3];
const b = a;
a === b; // true (same reference!)
Practical if/else Patterns
// Guard clauses — return early instead of nesting
function processUser(user) {
// Bad — deeply nested:
if (user) {
if (user.isActive) {
if (user.hasPermission) {
// actual code buried 3 levels deep
return doSomething(user);
}
}
}
}
// Good — guard clauses, flat code:
function processUser(user) {
if (!user) return null;
if (!user.isActive) return { error: "User inactive" };
if (!user.hasPermission) return { error: "No permission" };
return doSomething(user); // happy path at end
}
// Checking multiple conditions
const isAdult = age >= 18;
const hasID = true;
const hasMoney = balance > 0;
if (isAdult && hasID && hasMoney) {
console.log("Entry allowed");
} else if (!isAdult) {
console.log("Must be 18+");
} else if (!hasID) {
console.log("Need valid ID");
} else {
console.log("Insufficient funds");
}
⚡ Key Takeaways
- Use
===for equality checks —==has confusing coercion rules - Guard clauses (early returns) keep code flat and readable
- Any truthy/falsy value works in an if condition — not just booleans
- Else-if chains evaluate top-to-bottom — order matters
- Objects and arrays use reference equality — two separate
{}are never equal
🎯 Practice Exercises
EXERCISE 1
Write a function getLetterGrade(score) that returns "A" (90+), "B" (80-89), "C" (70-79), "D" (60-69), or "F" (below 60).
EXERCISE 2
Write a function canDrive(age, hasLicense) that returns true only if the person is 16+ AND has a license. Use guard clauses.
EXERCISE 3 — CHALLENGE
FizzBuzz: Write a function that takes a number. If divisible by 3, return "Fizz". If by 5, return "Buzz". If by both, return "FizzBuzz". Otherwise return the number.