# JavaScript Control Flow: If-Else, Switch, and Ternary Operators Explained

In your quest while playing an RPG, you enter a dungeon, the game checks: *Is the player's health above 0? Does the player have the magic key?* Each check leads to a different outcome, a new scene, an enemy attack, or unlocked achievement. This decision making system is **control flow**.  
Without control flow, every player would experience the same game, in the same order, every time. Control flow is what makes a game react to your choices. In JavaScript, it makes your code react to data.

JavaScript runs your code **top to bottom, line by line**. Control flow structures let you *branch*, *skip*, or *repeat* parts of that code based on conditions.

```javascript
// Without control flow
console.log("Player enters dungeon");
console.log("Player finds treasure");
console.log("Player defeats boss");
```

Almost every real-world feature like login checks, permission systems, form validation, game state, etc. runs on control flow.

## The `if` Statement

The `if` statement is the simplest form of control flow. It only run the code IF a condition is true.

**Syntax:**

```javascript
if (condition) {
  // Code runs if condition is true
}
```

*Example: Checking Player Health*

```javascript
let playerHealth = 85;

// Steps:
// 1. Check: Is 85 > 50?  true
// 2. true, then run the code inside the block
if (playerHealth > 50) {
  console.log("Enter the dungeon"); // this gets printed
}
```

```javascript
let age = 17;

// Steps:
// Is 17 >= 18?  false, nothing prints
// The code inside the block is simply skipped
if (age >= 18) {
  console.log("Blood splatter animation activated"); // gets skipped
}
```

When the condition is `false`, JavaScript **skips** the block entirely and moves to next line of codes. There is no error and no output.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Use <code>===</code> (strict equality) instead of <code>==</code> (loose equality) for comparisons. <code>===</code> checks both value and type.</div>
</div>

## Truthy and Falsy Values

Every `if` condition is evaluated as either `true` or `false`. But in JavaScript, you don't always need to write a direct boolean, *any* value can be used as a condition. JavaScript converts it to a boolean behind the scenes.  
Imagine a game inventory: **IF** the player has a sword (the variable exists and has a value), allow attack. **IF** the inventory slot is empty (`null`, `0`, or `""`), block the action. The game doesn't need a strict `true/false`, it just checks for falsy values.

### The Falsy Values in JavaScript

These are the values that evaluate to `false` in a condition. Everything else is truthy

```javascript
// falsy values
if (false)     { } // false itself
if (0)         { } // the number zero
if ("")        { } // empty string
if (null)      { } // null
if (undefined) { } // undefined
if (NaN)       { } // Not a Number
```

**Truthy vs Falsy in Action**

```javascript
let playerName = "";   // empty string = FALSY
let score      = 0;    // zero = FALSY
let lives      = 3;    // non-zero number = TRUTHY
let weapon     = null; // null = FALSY

if (playerName) {
  console.log("Hello, " + playerName);
} else {
  console.log("No player name set");   //  runs
    // Output: No player name set
}

if (score) {
  console.log("Score: " + score);
} else {
  console.log("Score: 0. Game just started"); // runs
    // Output: Score: 0. Game just started
}

if (lives) {
  console.log("Player is alive");  // runs (3 is truthy)
    // Output: Player is alive
}

if (weapon) {
  console.log("Ready to fight!");
} else {
  console.log("No weapon equipped.");  // runs (null is falsy)
    // Output: No weapon equipped.
}
```

Truthy/falsy checks are used constantly in real code, checking if a form field is filled, if an API returned data, or if a variable was set. E.g. `if (username)` is cleaner than `if (username !== "" && username !== null && username !== undefined)`.

## The `if-else` Statement

The `if...else` statement executes a statement if a specified condition is truthy. If the condition is falsy, another statement in the optional `else` clause will be executed. The else block acts as fallback.  
**IF** the player lands on the platform, he is safe, **ELSE** falls into the pit. One of the two outcomes happens.

**Syntax:**

```javascript
if (condition) {
  // Runs when condition is TRUE
} else {
  // Runs when condition is FALSE
}
```

![](https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/15e0a95b-29db-43b7-81e7-6342ae2780ae.png align="center")

```javascript
let isLoggedIn = false;

if (isLoggedIn) {
  console.log("Welcome back, adventurer!");
} else {
  console.log("Please log in to continue."); // runs
}

// isLoggedIn is false. else block runs
```

`else` cannot exist without a matching `if`case. They are always a pair.

### The `else if` Ladder

Two outcomes aren't always enough. Real logic often has multiple lanes. The `else if` ladder lets you chain conditions and find the first one that's true. In a racing game, your speed determines your rank: **IF** speed > 200 → "S Rank". **ELSE IF** speed > 150 → "A Rank". **ELSE IF** speed > 100 → "B Rank". **ELSE** → "C Rank". Only the first matching condition wins.

**Syntax:**

```javascript
if (condition1) {
  // Runs if condition1 is true
} else if (condition2) {
  // Runs if condition2 is true (and condition1 was false)
} else if (condition3) {
  // Runs if condition3 is true (and above were false)
} else {
  // Runs if ALL conditions above were false
}
```

Example:

```javascript
let score = 78;

if (score >= 90) {
  console.log("Legendary");
} else if (score >= 75) {
  console.log("Strong performance"); // runs
} else if (score >= 60) {
  console.log("You were a good support");
} else if (score >= 40) {
  console.log("Level Passed");
} else {
  console.log("Wasted");
}

// score = 78
// Is 78 >= 90?  false, move on
// Is 78 >= 75? TRUE, run this block, stop here
```

JavaScript stops at the **first true condition**. Always put the most specific condition first. For ranges, check highest values first if using `>=`.

### Nested `if`

An `if` statement inside an `if` statement is called **nesting.**

```javascript
if (condition1)
  statement1
else
  if (condition2)
    statement2
  else
    if (condition3)
      statement3
```

In a RPG: **IF** the player has a key, check **IF** the player's level is high enough to unlock the boss chamber. There are two gates, one inside the other. Pass both to proceed.

```javascript
let hasKey = true;
let playerLevel = 8;

// Outer if: check the first gate
if (hasKey) {
  console.log("Key found. Checking level..."); //runs

  // Inner if: check the second gate
  if (playerLevel >= 10) {
    console.log("Boss chamber unlocked!");
  } else {
    console.log("Level too low. Train more"); // runs
  }

} else {
  console.log("No key. Find it first.");
}

// Execution:
// Line 1: hasKey = true, outer if runs 
// Line 2: logs "Key found..."
// Line 3: playerLevel (8) >= 10? = false, inner else runs
// Line 4: logs "Level too low..."
```

## The Ternary Operator

The ternary operator (`?` `:`) is JavaScript's shorthand for a simple `if-else` that returns a value. It's called "ternary" because it takes *three* parts: a condition followed by a question mark (`?`), then an expression to execute if the condition is truthy followed by a colon (`:`), and finally the expression to execute if the condition is falsy.

**Syntax:**

```javascript
condition ? exprIfTrue : exprIfFalse
```

`if-else` vs `ternary`:

```javascript
// Regular if-else:
let lives = 3;
let status;
if (lives > 0) {
  status = "alive";
} else {
  status = "game over";
}

// Same thing with ternary
let status2 = lives > 0 ? "alive" : "game over";

console.log(status);   // "alive"
console.log(status2);  // "alive"
```

Use the ternary operator only for simple, single-value decisions. If the logic needs more than one line or action per branch, use a full `if-else` as it'll be much easier to read and debug.

## The `switch` Statement

When you're checking a single value against many *exact matches*, the `switch` statement is cleaner and easier to read than a tall ladder of `else if`. The `switch` statement evaluates an expression, matching the expression's value against a series of `case` clauses, and executes statements after the first `case` clause with a matching value, until a `break` statement is encountered. The `default` clause of a `switch` statement will be jumped to if no `case` matches the expression's value.  
**Syntax:**

```javascript
switch (expression) {
  case value1:
    // Code for value1
    break;          // Stops execution here
  case value2:
    // Code for value2
    break;
  default:
    // Runs if no case matched 
}
```

Think of a game's item menu. You press a button: **1** then equip sword, **2**\- use potion, **3**\- open map, **4**\- cast spell. Each key has an exact assigned action, a perfect job for `switch`.

Example:

```javascript
let key = 3;
let menu;

switch (key) {
  case 1:
    menu = "Equip Sword";
    break;
  case 2:
    menu = "Open Map";
    break;
  case 3:
    menu = "Drink Potion";
    break;
  case 4:
    menu = "Call Pet";
    break;
  default:
    menu = "No Action";
}

console.log(menu); // Drink Potion
```

**What happens without break?**

```javascript
let key = 2;

switch (key) {
  case 1:
    console.log("Map");
    break;
  case 2:
    console.log("Weapon");
    // No break! Code FALLS THROUGH to case 3
  case 3:
    console.log("Potion");
    break;
}

// Output
// Weapon
//Potion
```

Without `break`, JavaScript *falls through* to the next case and keeps running, regardless of whether it matches. This is a bug. Always end each case with `break` (or `return` inside a function).

**Intentional Fall-through**

```javascript
let day = 6;

switch (day) {
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
    console.log("Weekday. Go to work");
    break;
  case 6:
  case 7:
    console.log("Weekend. Time to game!"); // runs
    break;
  default:
    console.log("Unknown day");
}
// day = 6. case 6, falls through to case 7 block intentionally
```

### `switch` vs `if-else`: When to Use Which?

| Situation | Use if-else | Use switch |
| --- | --- | --- |
| **Checking ranges** | marks >= 90, marks >= 75… | ❌ switch can't do ranges |
| **Exact value matching** | Works, but verbose | day === 1, day === 2… |
| **Boolean conditions** | isLoggedIn, hasKey | ❌ switch needs a value |
| **Many fixed options** | Gets messy fast | Clean, readable, scalable |
| **Complex logic per branch** | Flexible | Complicated |
| **Grouping identical outcomes** | Use `||` operator | Stack empty cases cleanly |

If we see it with code:

```javascript
// Using if-else 
let direction = "north";

if (direction === "north") {
  console.log("Moving north");
} else if (direction === "south") {
  console.log("Moving south");
} else if (direction === "east") {
  console.log("Moving east");
} else if (direction === "west") {
  console.log("Moving west");
} else {
  console.log("Unknown direction");
}
______________________________________________________________________

// Using switch
let direction = "north";

switch (direction) {
  case "north": console.log("Moving north"); break;
  case "south": console.log("Moving south"); break;
  case "east": console.log("Moving east");  break;
  case "west": console.log("Moving west");  break;
  default: console.log("Unknown direction");
}

//Output
//Moving north
```

## Quick Recap

<table style="min-width: 75px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><td colspan="1" rowspan="1"><p><strong>Structure</strong></p></td><td colspan="1" rowspan="1"><p><strong>Use Case</strong></p></td><td colspan="1" rowspan="1"><p><strong>Key Strength</strong></p></td></tr><tr><td colspan="1" rowspan="1"><p><code>if</code></p></td><td colspan="1" rowspan="1"><p>Simple, single condition</p></td><td colspan="1" rowspan="1"><p>Minimalist</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>if...else</code></p></td><td colspan="1" rowspan="1"><p>Binary choices (this OR that)</p></td><td colspan="1" rowspan="1"><p>Readability</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>else if</code></p></td><td colspan="1" rowspan="1"><p>Range checks (<code>score &gt;= 90</code>)</p></td><td colspan="1" rowspan="1"><p>Flexible branching</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>Ternary</code></p></td><td colspan="1" rowspan="1"><p>Quick variable assignment</p></td><td colspan="1" rowspan="1"><p>Clean, one-liner</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>switch</code></p></td><td colspan="1" rowspan="1"><p>Multiple exact matches</p></td><td colspan="1" rowspan="1"><p>Scalable for menus/states</p></td></tr></tbody></table>

##   
**Reference Articles:**

*   [MDN : Control Flow and Error Handling](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling)
    
*   [MDN : if...else](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else)
    
*   [MDN : switch statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch)
    
*   [MDN : Truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and [Falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)
    
*   [MDN : Ternary Operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_operator)
