Control Flow — if, switch, ternary

শাখা সিদ্ধান্তের যুক্তি

~25 min Beginner 12 practice problems Live runner

1. if / else if / else

if.js
function grade(score) {
    if      (score >= 80) return "A";
    else if (score >= 70) return "B";
    else if (score >= 60) return "C";
    else if (score >= 50) return "D";
    else                return "F";
}
console.log(grade(82), grade(75), grade(42));
JS-এর if-এ যেকোনো expression-কে condition হিসেবে দেওয়া যায় — তা truthy হলে block চলবে, falsy হলে চলবে না।

2. The Guard Clause Pattern

Instead of nesting ifs deeply, return early on the bad cases. The "happy path" stays at the left margin, easy to read.

⚠️ Nested (hard to read)

function pay(user) {
    if (user) {
        if (user.balance >= 100) {
            if (user.active) {
                doPay(user);
            }
        }
    }
}

✅ Guard clauses

function pay(user) {
    if (!user) return;
    if (user.balance < 100) return;
    if (!user.active) return;
    doPay(user);
}

3. switch & The Fall-Through Trap

switch compares with ===. Cases fall through unless you write break — a famous bug source.

switch.js
function describe(day) {
    switch (day) {
        case "Sat":
        case "Sun":
            return "weekend";
        case "Fri":
            return "jumma";
        default:
            return "weekday";
    }
}
console.log(describe("Sun"));   // "weekend"
console.log(describe("Fri"));   // "jumma"
console.log(describe("Mon"));   // "weekday"
Modern alternative For dictionary-style branching, an object literal is often cleaner than a switch — see Section 5.

4. The Ternary ? :

Three operands: condition, then-value, else-value. It's an expression, so you can put it inside template literals, returns, and assignments.

ternary.js
const age = 19;
const label = age >= 18 ? "adult" : "minor";
console.log(label);

// In a template literal
const n = 3;
console.log(`${n} item${n === 1 ? "" : "s"}`);  // "3 items"

// Avoid nested ternaries — use if/else if instead
const ugly = age < 13 ? "child" : age < 20 ? "teen" : "adult";
console.log(ugly);

5. Object Maps Replace Many Switches

map.js
const ICONS = {
    success: "✅",
    error:   "❌",
    info:    "ℹ️",
    warn:    "⚠️",
};
const kind = "warn";
console.log(ICONS[kind] ?? "?");  // "⚠️"

// Same idea with functions
const ops = {
    add: (a, b) => a + b,
    sub: (a, b) => a - b,
    mul: (a, b) => a * b,
};
console.log(ops.mul(6, 7));   // 42

6. ?? vs || — One More Time

The right operator changes behaviour with falsy-but-valid values.

defaults.js
function setVolume(v) {
    const bad  = v || 50;     // 0 → 50  (bug if 0 means mute!)
    const good = v ?? 50;     // only null/undefined → 50
    return { bad, good };
}
console.log(setVolume(0));         // { bad: 50, good: 0 }
console.log(setVolume(undefined)); // { bad: 50, good: 50 }

7. Glossary (শব্দকোষ)

TermMeaningবাংলায়
BranchWhere execution can take different paths based on a condition.Condition অনুযায়ী আলাদা পথে যাওয়ার জায়গা।
Guard clauseEarly return on bad/empty cases to flatten nesting.খারাপ case-এ আগেভাগে return — nested if কমায়।
Fall-throughSwitch case continuing into the next without break.break ছাড়া switch case পরের case-এ গড়িয়ে যায়।
Ternarycond ? a : b — three-operand conditional expression.cond ? a : b — এক-line conditional expression।
Truthy/FalsyWhether a value behaves as true/false in a condition.Condition-এ value true/false-এর মতো আচরণ করছে কিনা।
??Nullish coalescing — fallback only on null/undefined.শুধু null/undefined-এ fallback দেয়।
?.Optional chaining — safe nested property access.Nested property নিরাপদে read করে।
Lookup mapObject/array used to replace a switch with a key→value mapping.Switch-এর বদলে object বা array দিয়ে key→value mapping।
সংক্ষেপে: বেশিরভাগ ক্ষেত্রে if/else if/else; nested হয়ে গেলে guard clause দিয়ে flatten করুন। switch-এ break ভুলে গেলে fall-through bug। ছোট condition-এ ternary ভালো, nested ternary খারাপ। Map/array দিয়ে অনেক switch-কে এক লাইনে বদলে দিতে পারেন।

8. Practice Problems

  1. Write fizzBuzz(n) that prints "Fizz" / "Buzz" / "FizzBuzz" / number for 1–15.
    ✨ Show Answer
    a1.js
    for (let i = 1; i <= 15; i++) {
        if      (i % 15 === 0) console.log("FizzBuzz");
        else if (i % 3  === 0) console.log("Fizz");
        else if (i % 5  === 0) console.log("Buzz");
        else                  console.log(i);
    }
  2. Refactor a 4-level nested if into guard clauses.
    ✨ Show Answer
    a2.js
    function canDrive(p) {
        if (!p) return "no person";
        if (!p.license) return "no license";
        if (p.age < 18) return "too young";
        if (p.suspended) return "suspended";
        return "ok";
    }
    console.log(canDrive({ license: true, age: 22 }));
  3. Use switch to convert weekday number 0–6 to its English name.
    ✨ Show Answer
    a3.js
    function dayName(d) {
        switch (d) {
            case 0: return "Sun";
            case 1: return "Mon";
            case 2: return "Tue";
            case 3: return "Wed";
            case 4: return "Thu";
            case 5: return "Fri";
            case 6: return "Sat";
            default: return "?";
        }
    }
    console.log(dayName(3));
  4. Replace the same switch with an object map.
    ✨ Show Answer
    a4.js
    const DAYS = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
    console.log(DAYS[3] ?? "?");
  5. Write greet(hour) that returns "morning" / "afternoon" / "evening" / "night".
    ✨ Show Answer
    a5.js
    function greet(h) {
        if (h < 5)  return "night";
        if (h < 12) return "morning";
        if (h < 17) return "afternoon";
        if (h < 21) return "evening";
        return "night";
    }
    console.log(greet(9), greet(14), greet(22));
  6. Use a ternary to label a number as "even" or "odd".
    ✨ Show Answer
    a6.js
    [3, 4, 7].forEach(n =>
        console.log(n, n % 2 === 0 ? "even" : "odd"));
  7. Show that x ?? "y" ignores 0 but x || "y" doesn't.
    ✨ Show Answer
    a7.js
    const x = 0;
    console.log(x ?? "y");   // 0
    console.log(x || "y");   // "y"
  8. Write classify(n) that returns "negative", "zero", or "positive".
    ✨ Show Answer
    a8.js
    const classify = n => n < 0 ? "negative" : n === 0 ? "zero" : "positive";
    [-3, 0, 5].forEach(n => console.log(n, classify(n)));
  9. Use optional chaining + ternary to print a user's city or "Unknown".
    ✨ Show Answer
    a9.js
    const u = { name: "Arif" };
    console.log(u.address?.city ?? "Unknown");
  10. Detect leap year using a single boolean expression.
    ✨ Show Answer
    a10.js
    const leap = y => (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0;
    [2024, 2025, 1900, 2000].forEach(y => console.log(y, leap(y)));
  11. Why is fall-through useful in switch sometimes?
    ✨ Show Answer

    Answer: When several cases share the same body, omit break so they fall through to a single block — e.g. case "Sat": case "Sun": return "weekend"; avoids duplication. The trap is accidental fall-through; lint rules can require an explicit // falls through comment.

  12. Build an FX-rate lookup using an object map; default to "1" if currency unknown.
    ✨ Show Answer
    a12.js
    const rates = { USD: 110, EUR: 120, INR: 1.3, BDT: 1 };
    const rate = c => rates[c] ?? 1;
    console.log(rate("USD"), rate("INR"), rate("XYZ"));

Summary — Module 09

if/else if/else handles most branches. Use guard clauses to flatten nesting. switch compares with ===, but always remember break. The ternary is great for short, expression-shaped decisions; avoid nesting them. Object literals replace many switch blocks. Use ?? over || when 0 / "" are valid.

গভীর nested if-এর বদলে guard clause ব্যবহার করুন। switch-এ break ভুলবেন না। ছোট ternary ভালো, nested ternary খারাপ।

Next Module → Loops — for, while, for...of, for...in।