Computer Programming 1 (JavaScript) • Conditionals, Loops & Common Patterns

If/Else Chains — I can write if/else and else-if chains and design condition order to avoid logic bugs.

Master the art of branching logic so your programs make the right decision every time.

A JavaScript data file with code brackets and a laptop.
Inside this lesson 10 sections 5 questions 6 figures

SECTION 1

Historical Context & Motivation

Every useful program must make decisions. Should the game character jump or duck? Should the shopping cart apply a discount or charge full price? From the very earliest days of computing, programmers needed a way to tell the machine: "If this condition is true, do one thing; otherwise, do something else." This idea — conditional branching — is one of the most fundamental concepts in all of computer science, and it has a surprisingly rich history.

1843 • Ada Lovelace's Notes

Ada Lovelace described how Charles Babbage's Analytical Engine could make decisions by testing conditions and branching to different instruction sequences — the first written description of conditional logic in computing.

1957 • FORTRAN's IF Statement

IBM's FORTRAN became the first widely-used high-level language. Its arithmetic IF statement let programmers branch based on whether a value was negative, zero, or positive, making decision-making accessible beyond machine code.

1972 • C Language & Structured Control Flow

Dennis Ritchie designed C with clean if/else if/else syntax that replaced messy GOTO jumps. This structured approach became the template for nearly every modern language, including JavaScript.

1995 • JavaScript Brings Conditionals to the Web

Brendan Eich created JavaScript in just ten days, borrowing C-style if/else syntax. Suddenly web pages could react to user input, validate forms, and change dynamically — all powered by conditional chains.

The core question that if/else chains answer has remained the same for over 180 years: How can a program choose different paths of execution based on data it receives at runtime? Today you will learn to write these decision structures in JavaScript and, just as importantly, to order your conditions so they don't silently produce wrong results.

SECTION 2

Core Principles of If/Else Chains

Before writing any code, you need to understand the building blocks. An if/else chain is a series of condition tests that the JavaScript engine evaluates from top to bottom. The moment one condition evaluates to true, the engine runs that block and skips every remaining branch. If no condition matches, an optional else block serves as the default fallback. The following principles govern how these chains behave.

1

Top-Down Evaluation

JavaScript checks conditions in the exact order you write them. The first true condition wins, and all later branches are skipped — even if they would also be true.
2

Mutual Exclusivity

In an if/else-if/else chain, exactly one block (or zero, if there is no else) will execute. This differs from separate if statements, where multiple blocks can run.
3

Condition Order Matters

Placing a broader condition before a narrower one can "shadow" the narrow branch so it never runs. Always order from most specific to least specific.
4

The else Safety Net

An else block catches every case not handled above it. Including one prevents unexpected "silent failures" where no branch runs and no output is produced.
5

Boolean Expressions Are the Gate

Each condition must resolve to a Boolean value (true or false). JavaScript's type coercion can cause tricky bugs if you accidentally test a non-Boolean value.
✦

KEY TAKEAWAY

Think of an if/else chain like a series of locked doors in a hallway. You walk down the hall and try each door in order. The first door that opens is the one you walk through — and once you're through, you skip every remaining door. If you put the widest, easiest-to-open door first, you'll never even reach the specific doors further down the hall.

SECTION 3

Visual Explanation — How an If/Else Chain Flows

If / Else-If / Else — Top-Down FlowStart: score = 85score >= 90?TRUEFALSEprint "A"score >= 80?TRUE ✓FALSEprint "B"score >= 70?TRUEFALSEprint "C"print "F"else →EXIT CHAIN
With score = 85, the first diamond (score >= 90) evaluates to false, so control flows down. The second diamond (score >= 80) evaluates to true, so "B" is printed and the entire chain is exited. The remaining conditions are never tested.

Notice how each diamond represents one condition check. The TRUE arrow leads to an action block, and after that action runs, control jumps straight to the exit — skipping every diamond below. The FALSE arrow drops down to the next condition. The final else block at the bottom has no diamond because it catches everything that fell through above.

SECTION 4

How If/Else Chains Work Under the Hood

The Anatomy of an If/Else Chain

An if/else chain in JavaScript follows a strict syntax. The keyword if is followed by a condition wrapped in parentheses, then a block of code in curly braces. Additional branches use else if (two words, no hyphen), and the optional catch-all uses else alone. Here is the general pattern:

GENERAL SYNTAX

if(conditionA)blockAelseif(conditionB)blockBelseif(conditionC)blockCelsedefaultBlockif (conditionA) { blockA } else if (conditionB) { blockB } else if (conditionC) { blockC } else { defaultBlock }

conditionA, conditionB, conditionC — Boolean expressions evaluated top to bottom. blockA … defaultBlock — the code that runs when the corresponding condition is the first to evaluate to true.

Separate If Statements vs. If/Else-If Chain

A common source of bugs is writing multiple standalone if statements when you actually need an if/else-if chain. With separate if blocks, every condition is tested independently, and multiple blocks can execute. With an if/else-if chain, only the first matching branch runs. Consider these two snippets:

Separate if StatementsIf/Else-If Chain
if (x > 5) { log("big"); } if (x > 3) { log("medium"); } if (x > 0) { log("positive"); }if (x > 5) { log("big"); } else if (x > 3) { log("medium"); } else if (x > 0) { log("positive"); }
When x = 7, all three conditions are true, so all three messages print.When x = 7, only "big" prints because the chain exits after the first match.

Separate if blocks vs. a single if/else-if chain with x = 7

⚠

Common Mistake

Accidentally writing separate if blocks instead of linking them with else if is one of the most frequent bugs beginners introduce. If your branches are meant to be mutually exclusive, always connect them with else if.

SECTION 5

Designing Condition Order to Avoid Logic Bugs

The order of your conditions can make or break your program. A shadowed branch occurs when a broader condition appears before a narrower one, causing the narrow branch to become unreachable. This is the single most common logic bug in if/else chains, and it usually produces no error — the program runs, but it gives the wrong answer.

Condition Order: Wrong vs. Correct❌ WRONG ORDER (Broad First)if (score >= 60) {grade = "D";} else if (score >= 70) {grade = "C"; // ⛔ never reached} else if (score >= 80) {grade = "B"; // ⛔ never reached} else if (score >= 90) {grade = "A"; // ⛔ never reached} else {grade = "F";}score = 95 → grade = "D"Every score ≥ 60 is caught by the first branch!✅ CORRECT ORDER (Narrow First)if (score >= 90) {grade = "A";} else if (score >= 80) {grade = "B";} else if (score >= 70) {grade = "C";} else if (score >= 60) {grade = "D";} else {grade = "F";}score = 95 → grade = "A" ✓Most restrictive condition tested first.Rule: Order conditions from most specific (narrowest) to least specific (broadest).
The left panel shows the wrong order — score >= 60 is tested first, so a score of 95 is incorrectly graded as "D." The right panel fixes the bug by placing the narrowest condition (score >= 90) at the top.

The Golden Rule of Condition Order

When your conditions test overlapping ranges (like >= thresholds), always arrange them from most restrictive to least restrictive. A condition is more restrictive when fewer values can satisfy it. For numeric thresholds going upward, this means testing the highest value first. For thresholds going downward, test the lowest value first.

  • ✓ Overlapping >= checks: Start with the highest threshold. Example: 90, then 80, then 70, then 60.
  • ✓ Overlapping <= checks: Start with the lowest threshold. Example: 10, then 20, then 30.
  • ✓ Non-overlapping conditions: Order doesn't matter logically, but putting the most common case first can improve readability.
  • ✓ Exact-match checks (===): Order is irrelevant since each condition matches exactly one value, but consider using a switch statement instead for clarity.

SECTION 6

Worked Example — Movie Ticket Pricing

A movie theater charges different ticket prices based on the customer's age. Children (under 13) pay $8, teens (13–17) pay $10, adults (18–64) pay $14, and seniors (65 and over) pay $9. Let's write a complete if/else chain and then trace through it for a customer who is 16 years old.

Determine Ticket Price for age = 16

  1. 1

    Step 1 — Identify the Conditions and Order

    We have four age categories. The boundaries are 13, 18, and 65. Since we are using < for the first check, we start with the youngest group and work upward. This prevents shadowing because each successive branch is only reached when the age is at least as high as the previous boundary.
    Order: child → teen → adult → senior (ascending)
  2. 2

    Step 2 — Write the Code

    Here is the complete chain: let age = 16; let price; if (age < 13) { price = 8; } else if (age < 18) { price = 10; } else if (age < 65) { price = 14; } else { price = 9; }
    Four branches cover every possible age, and every boundary is tested exactly once.
  3. 3

    Step 3 — Trace Execution for age = 16

    Condition 1: 16 < 13 → false. Move to next branch. Condition 2: 16 < 18 → true. The engine enters this block and sets price = 10. All remaining branches (adult and senior) are skipped.
    price = 10 (teen ticket)
  4. 4

    Step 4 — Verify Edge Cases

    Edge-case testing is critical. At age = 13: condition 1 is false (13 < 13 is false), condition 2 is true (13 < 18), so price = 10. At age = 18: conditions 1 and 2 are false, condition 3 is true (18 < 65), so price = 14. At age = 65: conditions 1–3 are all false, so the else block sets price = 9. All boundaries behave as expected.
    Edge cases confirmed: 13 → $10, 18 → $14, 65 → $9 ✓
💡

Pro Tip: Why We Didn't Need && Here

Notice that we never wrote age >= 13 && age < 18. Because the chain exits on the first true branch, reaching the second else if already guarantees age >= 13. The chain's structure handles the lower bound implicitly, making the code cleaner and less error-prone.

SECTION 7

If/Else Chains vs. Other Decision Structures

JavaScript offers several ways to make decisions. An if/else chain is the most flexible, but it is not always the best tool. Understanding when to use which structure will make your code more readable and less prone to errors.

FeatureIf/Else ChainSwitch StatementTernary Operator
Best forRange checks, complex Boolean conditions, mixed comparisonsExact-value matching against a single variableSimple two-way assignments or inline expressions
ReadabilityGood for 2–5 branches; can become hard to follow beyond thatExcellent when comparing one value to many literalsCompact, but nesting ternaries becomes unreadable quickly
Handles ranges?Yes — its main strengthNot natively; requires workaroundsOnly for two-way decisions
Fall-through riskNone — branches are mutually exclusiveYes — forgetting break causes unintended fall-throughNone
Example useif (temp > 100) ... else if (temp > 80) ...switch (day) { case "Mon": ... }let msg = age >= 18 ? "adult" : "minor";

Comparing JavaScript decision structures

🔀

WHEN TO CHOOSE WHAT

Think of it like choosing a tool for a job. An if/else chain is a versatile adjustable wrench — it handles any kind of condition. A switch statement is a socket wrench — perfect when you're checking the same variable against specific values. A ternary is a quick-release bit — great for a fast, simple two-option task, but clumsy for anything more complex.

SECTION 8

Connection to Advanced Patterns

Once you are comfortable with if/else chains, you will encounter more advanced patterns that build on the same core idea of branching. Understanding how your current knowledge connects to these patterns will make the transition smoother when you encounter them in future courses or real-world projects.

What You Know NowAdvanced PatternWhy It Matters
If/else chain with simple conditionsNested if/else — chains inside chains for multi-dimensional decisionsNeeded when two or more independent factors affect the outcome (e.g., age AND membership status)
Condition order to avoid shadowingGuard clauses — early-return statements that handle edge cases before the main logicReduces nesting depth and makes functions easier to read in larger codebases
Boolean expressions as gatesShort-circuit evaluation — using && and || to combine or replace simple branchesEnables concise one-liner conditions and defensive checks like user && user.name
Else as a default handlerObject lookup maps — replacing long chains with a data structureWhen you have 10+ exact-match branches, an object lookup is cleaner and faster than a massive if/else chain

From beginner conditionals to professional patterns

You don't need to master these advanced patterns right now. The key insight is that every advanced branching technique is built on the same top-down, first-match-wins logic you are learning today. If you deeply understand how condition order affects execution, you will find guard clauses, short-circuit evaluation, and lookup maps intuitive when you encounter them.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain in your own words why the following code gives the wrong output when temperature = 105: if (temperature > 60) { console.log("Nice day"); } else if (temperature > 100) { console.log("Heat warning!"); }
Show answer
The condition temperature > 60 is broader than temperature > 100. Since 105 is greater than 60, the first branch matches and prints "Nice day." The chain then exits, and the "Heat warning!" branch is never evaluated. This is a classic shadowed-branch bug. To fix it, swap the order so temperature > 100 is checked first, because it is the more restrictive condition.

Question 2: BASIC CALCULATION

A shipping company charges based on package weight: under 2 lbs costs $5, 2–10 lbs costs $10, over 10 lbs costs $20. Write an if/else chain for a variable weight that sets a variable shippingCost to the correct amount. What does your code output when weight = 7?
Show answer
if (weight < 2) { shippingCost = 5; } else if (weight <= 10) { shippingCost = 10; } else { shippingCost = 20; } When weight = 7: the first condition (7 < 2) is false, the second condition (7 <= 10) is true, so shippingCost is set to 10. The else block is skipped. Notice we start with the lowest range and work upward. The implicit lower bound of the second branch (weight >= 2) is guaranteed by the chain structure.

Question 3: INTERMEDIATE

A theme park ride has the following rules: riders must be at least 48 inches tall AND at least 8 years old. If they are tall enough but too young, print "Come back when you're older." If they are old enough but too short, print "You need to grow a bit more." If both conditions fail, print "Sorry, not yet eligible." If both pass, print "Enjoy the ride!" Write the if/else chain for variables height and age.
Show answer
if (height >= 48 && age >= 8) { console.log("Enjoy the ride!"); } else if (height >= 48 && age < 8) { console.log("Come back when you're older."); } else if (height < 48 && age >= 8) { console.log("You need to grow a bit more."); } else { console.log("Sorry, not yet eligible."); } The most specific "both pass" condition comes first. Each subsequent branch handles a unique combination of the two factors. The else block at the end catches the case where both conditions fail. Because none of these conditions overlap, order among the middle two branches doesn't strictly matter, but placing the success case first is a common convention for readability.

Question 4: APPLIED

You are building a weather app. The variable windSpeed holds a number in mph. Display the following advisories: 0–25 → "Calm", 26–50 → "Breezy", 51–74 → "High Wind Warning", 75+ → "Severe Storm Warning". A classmate writes this code: if (windSpeed <= 74) { advisory = "High Wind Warning"; } else if (windSpeed <= 50) { advisory = "Breezy"; } else if (windSpeed <= 25) { advisory = "Calm"; } else { advisory = "Severe Storm Warning"; } Identify the bug, fix the code, and trace through your corrected version for windSpeed = 30.
Show answer
The bug is that the broadest condition (windSpeed <= 74) comes first. Any wind speed of 74 or below will always match the first branch, making the "Breezy" and "Calm" branches unreachable. Fixed code: if (windSpeed >= 75) { advisory = "Severe Storm Warning"; } else if (windSpeed >= 51) { advisory = "High Wind Warning"; } else if (windSpeed >= 26) { advisory = "Breezy"; } else { advisory = "Calm"; } Trace for windSpeed = 30: condition 1 (30 >= 75) is false, condition 2 (30 >= 51) is false, condition 3 (30 >= 26) is true → advisory = "Breezy". The remaining else is skipped. We reversed the direction so the most restrictive (highest) threshold is tested first.

Question 5: CRITICAL THINKING

Consider a function that assigns letter grades using non-overlapping range checks with &&: if (score >= 90 && score <= 100) { grade = "A"; } else if (score >= 80 && score <= 89) { grade = "B"; } // ...and so on Compare this approach to the streamlined version that uses only >= checks (as shown in Section 5). Which is better and why? Are there any scenarios where the explicit-range version is actually preferable?
Show answer
The streamlined version (only >= checks, descending order) is generally better because it is shorter, has fewer conditions to test at runtime, and has fewer opportunities for typos. Each branch's lower bound is implicitly established by the chain structure, so adding redundant lower-bound checks (using &&) duplicates information. However, the explicit-range version can be preferable in two scenarios: (1) when the ranges do not form a contiguous sequence — for example, if scores of 85–89 should be treated differently from 80–84, you might need explicit bounds; and (2) when the conditions are not evaluated in a single chain — for instance, if the checks are scattered across different functions, each check must be self-contained. In the common grading scenario with contiguous ranges, the streamlined chain is the cleaner and less error-prone choice.

SUMMARY

Lesson Summary

Summary

An if/else chain lets your JavaScript program choose between multiple paths of execution by testing conditions from top to bottom. The first true condition wins, its code block runs, and all remaining branches are skipped. The optional else block acts as a default safety net, catching any value not handled above. Remember that multiple standalone if statements are independent checks that can all fire, while an if/else if chain guarantees mutual exclusivity.

The most critical skill is condition order. When conditions overlap (such as range thresholds), always place the most specific (narrowest) condition first and the broadest last. Placing a broader condition first creates a shadowed branch — a logic bug that produces no error message but silently gives wrong results. Test your chains with edge-case values at each boundary. When your branches check exact values instead of ranges, consider a switch statement for clarity, and for simple two-way choices, a ternary operator keeps the code compact.

Varsity Tutors • Computer Programming 1 (JavaScript) • If/Else Chains