In this series, we use JSVisualizer, a free browser-based tool, to understand classic algorithms by watching them run. The first post gave a tour of the tool, and the second looked at for loops.

This time the topic is conditionals — if, else if, and else. The star of the show is the Control Flow view.

Where beginners get stuck

This program turns a score into a letter grade: 80 or above is an A, 60 or above is a B, and anything lower is a C.

let score = 72; let grade; if (score >= 80) { grade = "A"; } else if (score >= 60) { grade = "B"; } else { grade = "C"; } console.log(grade); 

It prints B. Short as it is, people who've just learned conditionals often wonder:

  • When is the else if checked? 72 is "60 or above", so it's a B. But was the "80 or above" condition checked too? What about the else?
  • Does the order of the conditions matter? What happens if you swap score >= 80 and score >= 60?
  • Checking which branch ran is tedious. Plenty of us have sprinkled console.log("got here") into every block just to find out.

JSVisualizer's Control Flow view turns your branches into a flowchart and shows, in different colors, the paths the program actually took and the ones it didn't.

Seeing it in the Control Flow view

How to read it

Paste the code into JSVisualizer, press ▶ Run, and open the Control Flow tab. Then press ▷ Human (one "human-friendly" step) twice. You'll see this:

Control Flow view: the if's true column holds grade = "A" (grayed out); its false column holds the else if, whose true column holds grade = "B" (×1) and whose false column holds grade = "C" (grayed out)

  • Rows marked with ◇ are conditions. Below each one, the flow splits: the left column is the true path (the condition held), and the right column is the false path (it didn't).
  • The else if sits inside the false side of the first if. "If it's not 80 or above, then check whether it's 60 or above" — that nesting is drawn right there in the shape.
  • The ×1 on each row is how many times that row ran.
  • Gray, dashed boxes are rows that never ran in this run. Here, grade = "A" and grade = "C" are gray.
  • The blue outline marks the row being executed right now (here, line 2, let grade;).

We're still on line 2, yet grade = "B" already shows ×1, and A and C are already gray. The Control Flow view shows you which paths the whole run takes, and how many times, right from the start. As you step forward, the blue outline follows that path to show where you are.

Stepping forward

Press ▷ Human three more times (five in total):

Control Flow view: the blue outline has reached grade = "B" on the true side of the else if

The blue outline has moved from if (score >= 80) to else if (score >= 60) to grade = "B". A score of 72 isn't 80 or above, so the first if sends execution down the false path, and the else if then sends it down the true path.

What the flowchart reveals

1. An else if is checked only when the conditions before it are false

In the flowchart, the else if lives inside the false side of the first if. That means else if (score >= 60) is checked only when score >= 80 turned out false. An if / else if / else chain checks its conditions from the top down and runs only the first branch whose condition is true — exactly one branch runs.

2. Put conditions in the wrong order, and some paths become unreachable

Let's swap the conditions and try a score of 95:

let score = 95; let grade; if (score >= 60) { grade = "B"; } else if (score >= 80) { grade = "A"; } else { grade = "C"; } console.log(grade); 

A score of 95 comes out as a B. The Control Flow view shows why:

Letter grade with conditions in the wrong order: only grade = "B" under if (score >= 60) has ×1; the else if (score >= 80) row itself, grade = "A", and grade = "C" are all gray

Not only is grade = "A" gray — the else if (score >= 80) row itself is gray. Since 95 already passes the first test, score >= 60, the score >= 80 condition is never even checked.

In fact, this program can never produce an A, whatever the score. Every score of 60 or above is caught by the first if, and anything below 60 isn't 80 or above either. Run it a few times with different scores and you'll see grade = "A" stay gray every time. The rule of thumb: check the strictest (narrowest) condition first.

3. Inside a loop, count the visits

When a conditional sits inside a loop, the ×N counts start to tell a story. Here's the classic FizzBuzz: print the numbers 1 to 15, but print Fizz for multiples of 3, Buzz for multiples of 5, and FizzBuzz for multiples of both.

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); } } 

Run it to the end and you'll see the following. (When else if chains nest deeply, the flowchart may run past the right edge; just scroll sideways to see the rest.)

FizzBuzz control flow: for ×16, if (i % 15 === 0) ×15, FizzBuzz ×1, else if (i % 3 === 0) ×14, Fizz ×4, else if (i % 5 === 0) ×10, Buzz ×2, console.log(i) ×8

  • Out of 1–15: FizzBuzz once (15), Fizz 4 times (3, 6, 9, 12), Buzz twice (5, 10), and the plain number 8 times — 15 in total.
  • else if (i % 3 === 0) ran ×14 and else if (i % 5 === 0) ran ×10. The numbers confirm that each one is checked only as many times as the conditions before it were false.
  • The for row shows ×16 because the condition i <= 15 was true 15 times and then false on the 16th check, which ended the loop. (It's the same "the loop variable goes one step past the end" effect we saw in the previous post.)

The lesson from point 2 applies here too: multiples of 15 are also multiples of 3, so i % 15 === 0 has to be checked first. See what happens when you change the order in the exercises below.

Try it yourself

Open the link below and press ▶ Run; the Control Flow view opens. Step forward with ▷ Human (the h key) and back with ◁ Human (H).

▶ Open in JSVisualizer (letter grade, Control Flow view)

To change the code, press ✏ Edit. Before each run, predict which rows will be gray:

  • Set score to 85, or to 40. Which path does it take?
  • Delete the final else { grade = "C"; }. What is grade when the score is 40?

Two more programs to play with:

Wrapping up

  • The Control Flow view draws your branches as a flowchart and shows which paths the whole run took, and how many times. Paths that never ran are grayed out.
  • An else if lives on the false side of the condition before it. Conditions are checked from the top, and only the first branch whose condition is true runs.
  • Put conditions in the wrong order and you get paths that never run (they stay gray). For branches inside a loop, the ×N counts let you check the numbers.

Next up: functions. We'll use the Call Stack view to see what actually happens when you call a function, and why two variables with the same name don't clash.