Skip to main content

Command Palette

Search for a command to run...

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

From Static Lines to Dynamic Worlds: Building Logic with Conditional Statements

Published
10 min read
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.

// 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:

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

Example: Checking Player Health

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
}
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.

💡
Use === (strict equality) instead of == (loose equality) for comparisons. === checks both value and type.

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

// 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

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:

if (condition) {
  // Runs when condition is TRUE
} else {
  // Runs when condition is FALSE
}
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 ifcase. 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:

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:

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.

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.

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:

condition ? exprIfTrue : exprIfFalse

if-else vs ternary:

// 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:

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:

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?

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

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 `

If we see it with code:

// 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

Structure

Use Case

Key Strength

if

Simple, single condition

Minimalist

if...else

Binary choices (this OR that)

Readability

else if

Range checks (score >= 90)

Flexible branching

Ternary

Quick variable assignment

Clean, one-liner

switch

Multiple exact matches

Scalable for menus/states

Reference Articles:

Simply JavaScript

Part 21 of 25

JavaScript is a quirky language. To master it, one should know to avoid its hidden traps along with its logic. This series showcase my journey through JS: the pain points, the breakthroughs, and the coding standards that I adopted from my mentors.

Up next

JS Operators: The Hidden Mechanics of Every Web App

Level Up Your Logic with RPG Mechanics

JavaScript Control Flow: If-Else, Switch, & Ternary Operator