Skip to content
JavaScript Control Flow Explained — Conditionals, Loops & Decision-Making

JavaScript Control Flow Explained — Conditionals, Loops & Decision-Making

DodaTech Updated Jun 6, 2026 9 min read

Control flow determines which code runs and how many times — it’s the difference between a program that runs straight through and one that makes decisions and repeats tasks.

What You’ll Learn

  • How to use if/else if/else to make decisions
  • When to use switch vs if
  • The difference between for, while, and do-while loops
  • How for...in and for...of iterate over objects and arrays
  • How break and continue control loop execution
  • How to avoid infinite loops and off-by-one errors

Why Control Flow Matters

Without control flow, every program runs line by line from top to bottom — no decisions, no repetition. Real applications need to validate forms (if email is valid, submit; else, show error), process lists (loop through every user in a database), and respond to events. The Durga Antivirus Pro dashboard uses control flow to check threat levels — if CPU usage is above 90%, trigger an alert; while threats are detected, scan continuously. The Doda Browser uses loops to iterate through open tabs and search results.

Learning Path

    flowchart TD
  A[JavaScript Basics] --> B[Operators]
  B --> C[Control Flow]
  C --> D[Functions]
  C --> E[Arrays]
  C --> F[Strings & Numbers]
  C --> G[You Are Here]
  
Prerequisites: You should know JavaScript — variables, data types, and JavaScript (especially comparison and logical operators).

What Is Control Flow?

Think of a program like a choose-your-own-adventure book. You read pages in order, but at key moments you make a choice (“If you open the door, turn to page 10. If you run away, turn to page 20.”). Control flow is exactly that — your code reaches a decision point and takes different paths based on conditions.

If / Else If / Else

The most basic decision maker:

const age = 20;

if (age >= 18) {
  console.log('Adult');       // This runs — age is 20
} else if (age >= 13) {
  console.log('Teen');        // Skipped — first condition was true
} else {
  console.log('Child');       // Skipped
}

Line by line explanation:

  • if (age >= 18) — Ask: “Is age 18 or more?” The answer is true, so the first block runs.
  • else if (age >= 13) — JavaScript only checks this if the first condition was false. Since we already matched, this is skipped.
  • else — The fallback. Runs only if all conditions above were false.

Why else if matters: Without it, you’d write multiple separate if statements that all get checked, even after one matches. That wastes CPU time and can cause bugs.

Ternary Operator

When you have a simple yes/no decision, the ternary operator is a shorter alternative:

const age = 20;
const status = age >= 18 ? 'Adult' : 'Minor';
//            condition   ? ifTrue  : ifFalse

Read it: “Is age >= 18? Then status is ‘Adult’. Otherwise, status is ‘Minor’.”

When to use it: Only for simple binary choices. If the logic gets complex, use a regular if statement for readability.

Switch Statement

When you’re comparing one value against many possible matches, switch is cleaner than a long chain of if/else:

const day = 3;
let dayName;

switch (day) {
  case 1:
    dayName = 'Monday';
    break;
  case 2:
    dayName = 'Tuesday';
    break;
  case 3:
    dayName = 'Wednesday';
    break;
  case 4:
    dayName = 'Thursday';
    break;
  case 5:
    dayName = 'Friday';
    break;
  default:
    dayName = 'Weekend';
}

console.log(dayName);  // 'Wednesday'

Critical: The break statement. Without break, execution “falls through” to the next case. This is called fall-through and is usually a bug:

switch (1) {
  case 1:
    console.log('One');   // Prints 'One'
    // No break! Falls through
  case 2:
    console.log('Two');   // Also prints 'Two' — probably not what you wanted
}

For Loop

Use a for loop when you know exactly how many times to repeat:

for (let i = 0; i < 5; i++) {
  console.log(i);  // 0, 1, 2, 3, 4
}

Breaking down the for loop:

  • let i = 0Initialization: Run once at the start. Create a counter variable starting at 0.
  • i < 5Condition: Checked before each iteration. If true, run the block.
  • i++Increment: Run after each iteration. Add 1 to the counter.

Think of it like counting laps on a track: “Start at 0 (initialization), while you’ve run fewer than 5 laps (condition), run one lap (body), then add 1 to your count (increment).”

Looping Through an Array

const fruits = ['apple', 'banana', 'cherry'];
for (let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);  // 'apple', 'banana', 'cherry'
}

fruits.length is 3, so the loop runs while i < 3 — accessing indices 0, 1, and 2.

While Loop

Use while when you don’t know how many iterations you need — the loop runs until a condition changes:

let i = 0;
while (i < 5) {
  console.log(i);  // 0, 1, 2, 3, 4
  i++;
}

Do-While Loop

A do-while loop always runs at least once, even if the condition is false:

let j = 0;
do {
  console.log(j);  // 0 (runs once)
  j++;
} while (j < 0);

Why use do-while? When you need to guarantee at least one execution — like showing a menu option before checking if the user wants to continue.

For…In (Object Keys)

Iterate over the keys (property names) of an object:

const person = { name: 'Alice', age: 25, city: 'NYC' };

for (const key in person) {
  console.log(key, person[key]);
  // name Alice
  // age 25
  // city NYC
}

Note: for...in iterates over keys as strings. The variable key takes values "name", "age", "city". You access the value with person[key].

For…Of (Iterable Values)

Iterate over the values of iterables (arrays, strings, maps, sets):

const numbers = [10, 20, 30];

for (const value of numbers) {
  console.log(value);  // 10, 20, 30
}

for (const char of 'hello') {
  console.log(char);  // h, e, l, l, o
}

Key difference: for...in gives you keys (property names). for...of gives you values. For arrays, for...in gives indices (0, 1, 2 as strings), while for...of gives the actual elements.

Break & Continue

Two special keywords that change loop behavior:

// break — exit the loop entirely
for (let i = 0; i < 10; i++) {
  if (i === 5) break;     // Stop when i is 5
  console.log(i);          // 0, 1, 2, 3, 4
}

// continue — skip to the next iteration
for (let i = 0; i < 10; i++) {
  if (i % 2 === 0) continue;  // Skip even numbers
  console.log(i);              // 1, 3, 5, 7, 9
}

Analogy: break is like hitting the emergency stop on a treadmill. continue is like stepping over a crack on the sidewalk — you skip that step and keep going.

Common Mistakes

1. Forgetting break in switch

switch (x) {
  case 1: console.log('One');
  case 2: console.log('Two');  // If x is 1, both print!
}

Fix: Always add break after each case, or use return inside a function.

2. Infinite loops

while (true) { }  // Never ends — CPU goes to 100%
for (let i = 0; i >= 0; i++) { }  // i always increases, never stops

Fix: Always ensure your loop condition eventually becomes false.

3. Using = instead of === in conditions

if (x = 5) { }  // Assignment, not comparison — always truthy

Fix: Use === for comparison. Some developers write if (5 === x) (Yoda conditions) to catch this error.

4. Off-by-one errors

const arr = [1, 2, 3];
for (let i = 0; i <= arr.length; i++) {
  console.log(arr[i]);  // arr[3] is undefined — out of bounds!
}

Fix: Use i < arr.length (strict less-than), not <=.

5. Using for...in on arrays

for...in iterates over keys (as strings) and includes inherited properties. Use for...of for arrays.

6. Modifying an array while iterating

const arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
  if (arr[i] % 2 === 0) arr.splice(i, 1);  // Skips elements after removal
}

Fix: Iterate backwards or use filter().

Practice Questions

  1. What’s the difference between for...in and for...of? for...in iterates over enumerable property keys (strings). for...of iterates over values of iterable objects.

  2. When should you use while vs for? Use for when you know the number of iterations. Use while when the loop runs until a condition changes.

  3. What happens if you omit break in a switch statement? Execution “falls through” to the next case — usually a bug, but sometimes intentional for grouping cases.

  4. How do you avoid an infinite loop? Ensure the loop condition eventually becomes false. The counter must change toward the boundary condition.

Challenge: Write a function that takes an array of numbers and returns only the even numbers. Solve it using a for loop, then rewrite it using filter().

FAQ

What is the difference between for...in and for...of?
for...in iterates over enumerable property keys (strings). for...of iterates over values of iterable objects (arrays, strings, maps, sets).
When should I use while vs for?
Use for when you know the number of iterations. Use while when the loop runs until a condition changes (unknown iterations).
What is fall-through in switch?
When a case block doesn’t have break, execution continues to the next case. Sometimes intentional (grouping cases), but usually a bug.
How do I break out of nested loops?
Use a labelled statement: outer: for(...) { for(...) { if(condition) break outer; } }.
What is the difference between post-increment (i++) and pre-increment (++i)?
i++ returns the value before incrementing. ++i returns the value after incrementing.
Can I use continue in a switch?
No — continue only works inside loops. Use break in switch cases.

Try It Yourself

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Control Flow Playground</title>
  <style>
    body { font-family: Arial, sans-serif; padding: 2rem; }
    pre { background: #f4f4f4; padding: 1rem; border-radius: 5px; }
  </style>
</head>
<body>
  <h1>Control Flow Sandbox</h1>
  <pre id="output"></pre>
  <script>
    const out = document.getElementById('output');
    let result = '';

    // If/else
    const age = 18;
    result += age >= 18 ? 'Adult\n' : 'Minor\n';

    // For loop
    result += '\nCounting to 5:\n';
    for (let i = 1; i <= 5; i++) {
      result += `${i} `;
    }

    // For...of
    result += '\n\nFruits:\n';
    const fruits = ['Apple', 'Banana', 'Cherry'];
    for (const fruit of fruits) {
      result += `${fruit} `;
    }

    out.textContent = result;
  </script>
</body>
</html>

What’s Next

Now that you can control program flow, learn about functions and arrays:

LessonDescription
JavaScript HomeBack to the JavaScript hub
https://tutorials.dodatech.com/programming-languages/javascript/js-functions/Functions & Scope — reusable code blocks
https://tutorials.dodatech.com/programming-languages/javascript/js-arrays/Arrays — ordered collections
https://tutorials.dodatech.com/programming-languages/javascript/js-strings-numbers/Strings, Numbers & Math
HTML FormsUse control flow to validate forms

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

What’s Next

Congratulations on completing this Js Control Flow tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro