3.2 Module 3 · Decisions & Loops

Decision Statements

Learn how to control what your program does next using if, else if, else, and switch — the building blocks of every branching decision in JavaScript.

1

Definition

Decision statements in JavaScript control the flow of execution based on conditions. They allow a program to choose different paths depending on whether a condition evaluates to true or false.

Without decision statements every program would run the same way every time — decision statements are what give code the ability to respond differently to different data, user input, or state.

2

Simple Way

Think of decision statements like choices you make in real life:

if "If it's raining — take an umbrella." Run this block when the condition is true
else if "If it's cloudy but not raining — bring a jacket." Check another condition
else "Otherwise — go as normal." The fallback when nothing else matched
switch Checks one value against many exact options — cleaner than a long chain of if/else if
3

Code Examples

Example 1 — if, else if, else
let marks = 75;

if (marks >= 90) {
  console.log("Grade A");
} else if (marks >= 75) {
  console.log("Grade B");
} else if (marks >= 60) {
  console.log("Grade C");
} else {
  console.log("Fail");
}
// Try changing marks to 95, 65, or 40
Output
Click ▶ Run to execute
Explanation
  • JavaScript checks conditions top to bottom and runs the first block that is true
  • Once a matching block runs, all remaining else if and else branches are skipped
  • else is optional — it acts as the default if no condition matched
Example 2 — switch Statement
let day = 3;

switch (day) {
  case 1:
    console.log("Monday");
    break;
  case 2:
    console.log("Tuesday");
    break;
  case 3:
    console.log("Wednesday");
    break;
  case 4:
    console.log("Thursday");
    break;
  case 5:
    console.log("Friday");
    break;
  default:
    console.log("Weekend");
}
Output
Click ▶ Run to execute
Explanation
  • switch compares one expression against multiple exact values using strict equality
  • break exits the switch — without it, execution falls through to the next case
  • default runs when no case matches — equivalent to else
Example 3 — Ternary Operator (Short if/else)
let age = 20;

// Long form
let message1;
if (age >= 18) {
  message1 = "Adult";
} else {
  message1 = "Minor";
}

// Short form — ternary
let message2 = age >= 18 ? "Adult" : "Minor";

console.log(message1); // Adult
console.log(message2); // Adult — same result, one line
Output
Click ▶ Run to execute
Explanation
  • Syntax: condition ? valueIfTrue : valueIfFalse
  • Ideal for simple two-way decisions that assign a value — keeps code concise
  • Avoid nesting ternaries — once it needs more than two outcomes, use if/else
Example 4 — Switch Fall-Through (Intentional & Accidental)
let signal = "red";

switch (signal) {
  case "red":
    console.log("Stop");
    break;
  case "yellow":
    console.log("Ready");
    break;
  case "green":
    console.log("Go");
    break;
  default:
    console.log("Invalid signal");
}

// Intentional fall-through — shared behaviour for multiple cases
let month = 4; // April
switch (month) {
  case 1: case 3: case 5: case 7:
  case 8: case 10: case 12:
    console.log("31 days");
    break;
  case 4: case 6: case 9: case 11:
    console.log("30 days");
    break;
  case 2:
    console.log("28 or 29 days");
    break;
}
Output
Click ▶ Run to execute
Explanation
  • When multiple cases should run the same code, stack them without break — intentional fall-through
  • The traffic signal example shows the clean form — one case, one action, one break
  • The month example shows how to group cases that share the same outcome
4

Real-Life Example

Two everyday systems that use decision logic constantly:

if
ATM: if PIN is correct → allow access
else if
ATM: else if wrong PIN twice → show warning
else
ATM: else (3rd wrong attempt) → block card
switch
Traffic signal: Red → Stop, Yellow → Ready, Green → Go
? :
App theme: dark mode on? Show white text : show dark text
default
Traffic signal: unknown colour → do not proceed
5

HTML + JavaScript Example

Click ▶ Preview, enter a score, and watch an if / else if / else chain assign the correct grade live.

Live in Browser — Grade Checker
<!DOCTYPE html>
<html>
<head><title>Decision Demo</title></head>
<body style="font-family:sans-serif;padding:24px;background:#f8f9fa">

  <h2>Check Result</h2>
  <input id="scoreInput" type="number" placeholder="Enter score (0–100)"
    style="padding:8px 12px;border:1px solid #ccc;border-radius:6px;
           font-size:1rem;width:210px">
  <button onclick="checkGrade()"
    style="margin-left:8px;padding:8px 18px;background:#f7df1e;border:none;
           border-radius:6px;cursor:pointer;font-weight:700;font-size:1rem">
    Check Grade
  </button>
  <div id="output" style="margin-top:16px;font-size:1.05rem;line-height:2"></div>

  <script>
    function checkGrade() {
      let score = Number(document.getElementById("scoreInput").value);
      let out   = document.getElementById("output");

      if (isNaN(score) || score < 0 || score > 100) {
        out.innerHTML = "<b style='color:red'>Enter a valid score between 0 and 100.</b>";
        return;
      }

      let grade, color;

      if (score >= 90)      { grade = "A — Excellent";  color = "#22c55e"; }
      else if (score >= 75) { grade = "B — Good";        color = "#3b82f6"; }
      else if (score >= 60) { grade = "C — Average";     color = "#f59e0b"; }
      else if (score >= 40) { grade = "D — Below Average"; color = "#f97316"; }
      else                  { grade = "F — Fail";         color = "#ef4444"; }

      out.innerHTML =
        "<b>Score:</b> " + score + "<br>" +
        "<b>Grade:</b> <b style='color:" + color + ";font-size:1.15rem'>" + grade + "</b>";
    }
  </script>

</body>
</html>
Live Preview
6

Tasks (Practice)

Easy Task 1 — Even or Odd
Starter code
let num = 7;

// Use if/else to print "Even" or "Odd"
  • Use num % 2 === 0 as the condition — if true it's even, else it's odd
  • Print the result with a label — e.g. "7 is Odd"
  • Try changing num to 12 and verify it prints "Even"
Medium Task 2 — Fruit switch
Starter code
let fruit = "apple";

// Write a switch with cases for apple, banana, mango
  • Add cases: "apple""Red fruit", "banana""Yellow fruit", "mango""King of fruits"
  • Add a default case: "Unknown fruit"
  • Test with each value — don't forget break in each case
7

MCQs

Q1
What will be the output?
let x = 5;

if (x > 10) {
  console.log("A");
} else {
  console.log("B");
}
Output
Run it to verify
  • A A
  • B B
  • C Both A and B
  • D Error
💡 B is correct. 5 > 10 is false, so the if block is skipped and the else block runs, printing "B".
Q2
What happens if break is missing from a switch case?
let n = 1;
switch (n) {
  case 1:
    console.log("One");
  case 2:
    console.log("Two");
    break;
  case 3:
    console.log("Three");
}
Output
Run it to verify
  • A Stops at that case
  • B Skips the next case
  • C Falls through to the next case
  • D Throws an error
💡 C is correct. Without break, JavaScript continues executing the next case even if its value doesn't match — called fall-through. Here case 1 runs, then falls into case 2. Both "One" and "Two" print.
Q3
Which statement is better for checking many exact fixed values?
  • A if / else if chain
  • B switch
  • C for loop
  • D while loop
💡 B is correct. switch is cleaner and more readable when checking one variable against many fixed values. Use if/else if for range conditions (>, <, >=) where switch does not apply.
8

Pro Tips & Extra Knowledge

  • 01

    Choose the right tool: use if/else for range conditions and switch for exact matches:

    if for ranges, switch for exact values
    let score = 82;
    
    // if — best for ranges
    if (score >= 90)      console.log("A");
    else if (score >= 75) console.log("B");
    else                  console.log("C");
    
    // switch — best for exact matches
    let lang = "JS";
    switch (lang) {
      case "JS":  console.log("JavaScript"); break;
      case "PY":  console.log("Python");     break;
      default:    console.log("Unknown");
    }
    Output
    Click ▶ Run to execute
  • 02

    You can use early return inside functions to avoid deeply nested if blocks — called a "guard clause":

    Guard clauses flatten nested ifs
    // ✗ Deep nesting — hard to read
    function checkAccess(age, hasID) {
      if (age >= 18) {
        if (hasID) {
          console.log("Access granted");
        }
      }
    }
    
    // ✓ Guard clauses — flat and readable
    function checkAccessClean(age, hasID) {
      if (age < 18) return console.log("Too young");
      if (!hasID)   return console.log("No ID");
      console.log("Access granted");
    }
    
    checkAccessClean(20, true);
    checkAccessClean(16, true);
    Output
    Click ▶ Run to execute
  • 03

    Use the ternary operator for simple two-way assignments — but switch back to if/else the moment logic gets complex:

    Ternary for simple assignments
    let temp = 35;
    
    // Ternary — clean for one simple choice
    let weather = temp > 30 ? "Hot" : "Cool";
    console.log(weather);
    
    // Use if/else when the logic needs more branches
    let advice;
    if (temp > 35)      advice = "Stay indoors";
    else if (temp > 25) advice = "Light clothing";
    else                advice = "Wear a jacket";
    console.log(advice);
    Output
    Click ▶ Run to execute
  • 04

    Always add a default to every switch — it catches unexpected values and prevents silent failures:

    default catches unexpected values
    function getStatus(code) {
      switch (code) {
        case 200: return "OK";
        case 404: return "Not Found";
        case 500: return "Server Error";
        default:  return "Unknown status: " + code; // always provide this
      }
    }
    
    console.log(getStatus(200));
    console.log(getStatus(403)); // caught by default
    Output
    Click ▶ Run to execute
Mini Challenge

There is no break after case 2 — predict every line that will print before running.

What does this print?
let value = 2;

switch (value) {
  case 1:
    console.log("One");
  case 2:
    console.log("Two");
  case 3:
    console.log("Three");
    break;
  default:
    console.log("Default");
}
Output
Think first, then run!
Step-by-Step Explanation
// value = 2

// case 1: value !== 1 → SKIPPED entirely

// case 2: value === 2 → MATCH — execution begins here
//   console.log("Two")   → prints "Two"
//   No break → FALL THROUGH to next case

// case 3: value !== 3, but we're already inside due to fall-through
//   console.log("Three") → prints "Three"
//   break → EXIT switch

// default: not reached — we already exited

// Final output:
//   Two
//   Three

// Key takeaway:
//   Without break, execution "falls through" every subsequent
//   case regardless of whether the value matches.
//   case 1 was skipped because we hadn't entered yet.
//   Once inside (at case 2), all remaining cases run until
//   a break or the end of the switch is reached.

// Fix: add break after case 2 if fall-through is unintended:
//   case 2:
//     console.log("Two");
//     break;  // ← prevents "Three" from printing