🔀 Control Flow

Conditionals and Loops

Control Flow

Control flow statements determine which code blocks execute and how many times. Master conditionals and loops to create dynamic, responsive programs.

🔀 Conditional Statements

if Statement

// Basic if
let age = 20;
if (age >= 18) {
    console.log('You are an adult');
}

// if...else
let score = 75;
if (score >= 60) {
    console.log('Pass');
} else {
    console.log('Fail');
}

// if...else if...else
let grade = 85;
if (grade >= 90) {
    console.log('A');
} else if (grade >= 80) {
    console.log('B');
} else if (grade >= 70) {
    console.log('C');
} else if (grade >= 60) {
    console.log('D');
} else {
    console.log('F');
}

// Nested if
let temperature = 25;
let isRaining = false;

if (temperature > 20) {
    if (isRaining) {
        console.log('Warm but rainy');
    } else {
        console.log('Perfect weather!');
    }
} else {
    console.log('Cold weather');
}

Truthy and Falsy

// Falsy values: false, 0, '', null, undefined, NaN
// Everything else is truthy

if (0) {
    console.log('Won\'t run');  // 0 is falsy
}

if (1) {
    console.log('Will run');    // 1 is truthy
}

if ('hello') {
    console.log('Will run');    // non-empty string is truthy
}

if ('') {
    console.log('Won\'t run');  // empty string is falsy
}

// Checking for existence
let user = { name: 'John' };
if (user) {
    console.log('User exists');
}

// Checking for value
let count = 0;
if (count) {
    console.log('Has count');  // Won't run
}

// Better check for zero
if (count !== undefined) {
    console.log('Count is defined');  // Will run
}

switch Statement

// switch for multiple conditions
let 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;
    case 6:
    case 7:
        dayName = 'Weekend';
        break;
    default:
        dayName = 'Invalid day';
}
console.log(dayName);  // 'Wednesday'

// Fall-through (when break is omitted)
let month = 2;
let season;

switch (month) {
    case 12:
    case 1:
    case 2:
        season = 'Winter';
        break;
    case 3:
    case 4:
    case 5:
        season = 'Spring';
        break;
    case 6:
    case 7:
    case 8:
        season = 'Summer';
        break;
    case 9:
    case 10:
    case 11:
        season = 'Fall';
        break;
    default:
        season = 'Invalid month';
}

// switch with strict comparison
let value = '1';
switch (value) {
    case 1:
        console.log('Number 1');
        break;
    case '1':
        console.log('String 1');  // This will match
        break;
}

Ternary Operator

// condition ? valueIfTrue : valueIfFalse
let age = 20;
let status = age >= 18 ? 'adult' : 'minor';
console.log(status);  // 'adult'

// Nested ternary (use sparingly!)
let score = 85;
let grade = score >= 90 ? 'A' :
            score >= 80 ? 'B' :
            score >= 70 ? 'C' :
            score >= 60 ? 'D' : 'F';

// In assignments
let price = isPremium ? 99.99 : 49.99;

// In returns
function getDiscount(isMember) {
    return isMember ? 0.2 : 0;
}

// Inline in templates
let message = `You are ${age >= 18 ? 'an adult' : 'a minor'}`;

🔁 Loops

for Loop

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

// Counting down
for (let i = 5; i > 0; i--) {
    console.log(i);  // 5, 4, 3, 2, 1
}

// Step by 2
for (let i = 0; i < 10; i += 2) {
    console.log(i);  // 0, 2, 4, 6, 8
}

// Multiple variables
for (let i = 0, j = 10; i < 5; i++, j--) {
    console.log(i, j);  // 0 10, 1 9, 2 8, 3 7, 4 6
}

// Nested loops
for (let i = 1; i <= 3; i++) {
    for (let j = 1; j <= 3; j++) {
        console.log(`i=${i}, j=${j}`);
    }
}

// Loop through array
let colors = ['red', 'green', 'blue'];
for (let i = 0; i < colors.length; i++) {
    console.log(colors[i]);
}

while Loop

// while loop
let count = 0;
while (count < 5) {
    console.log(count);
    count++;
}

// Condition checked before each iteration
let i = 10;
while (i < 5) {
    console.log(i);  // Never runs
}

// Infinite loop (be careful!)
// while (true) {
//     console.log('Forever');
//     // Need break to exit
// }

// Practical example: input validation
let password = '';
while (password.length < 8) {
    password = prompt('Enter password (min 8 chars):');
}

// Finding first match
let numbers = [1, 3, 5, 8, 9];
let target = 8;
let index = 0;

while (index < numbers.length) {
    if (numbers[index] === target) {
        console.log(`Found at index ${index}`);
        break;
    }
    index++;
}

do...while Loop

// Executes at least once
let num = 0;
do {
    console.log(num);
    num++;
} while (num < 5);

// Runs once even if condition is false
let x = 10;
do {
    console.log(x);  // Runs once: 10
    x++;
} while (x < 5);

// Practical: menu system
let choice;
do {
    console.log('1. Option A');
    console.log('2. Option B');
    console.log('3. Exit');
    choice = parseInt(prompt('Choose option:'));
    
    switch (choice) {
        case 1:
            console.log('Option A selected');
            break;
        case 2:
            console.log('Option B selected');
            break;
        case 3:
            console.log('Exiting...');
            break;
        default:
            console.log('Invalid option');
    }
} while (choice !== 3);

for...of Loop (ES6)

// Iterate over iterable objects (arrays, strings, etc.)
let fruits = ['apple', 'banana', 'orange'];
for (let fruit of fruits) {
    console.log(fruit);
}

// With strings
let text = 'hello';
for (let char of text) {
    console.log(char);  // h, e, l, l, o
}

// With sets
let uniqueNumbers = new Set([1, 2, 3, 4]);
for (let num of uniqueNumbers) {
    console.log(num);
}

// With maps
let map = new Map([
    ['name', 'John'],
    ['age', 30]
]);
for (let [key, value] of map) {
    console.log(`${key}: ${value}`);
}

// Get index with entries()
for (let [index, value] of fruits.entries()) {
    console.log(`${index}: ${value}`);
}

for...in Loop

// Iterate over object properties
let person = {
    name: 'John',
    age: 30,
    city: 'New York'
};

for (let key in person) {
    console.log(`${key}: ${person[key]}`);
}

// With arrays (iterates over indices)
let colors = ['red', 'green', 'blue'];
for (let index in colors) {
    console.log(`${index}: ${colors[index]}`);
}

// Note: for...in includes inherited properties
// Use hasOwnProperty to check
for (let key in person) {
    if (person.hasOwnProperty(key)) {
        console.log(`${key}: ${person[key]}`);
    }
}

// Better: Object methods
Object.keys(person).forEach(key => {
    console.log(`${key}: ${person[key]}`);
});

Object.entries(person).forEach(([key, value]) => {
    console.log(`${key}: ${value}`);
});

🛑 Loop Control

break

// Exit loop immediately
for (let i = 0; i < 10; i++) {
    if (i === 5) {
        break;  // Stop at 5
    }
    console.log(i);  // 0, 1, 2, 3, 4
}

// Find first match
let numbers = [1, 3, 5, 7, 8, 9];
let firstEven;

for (let num of numbers) {
    if (num % 2 === 0) {
        firstEven = num;
        break;  // Found it, exit
    }
}
console.log(firstEven);  // 8

// Break from nested loop
outerLoop:
for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (i === 1 && j === 1) {
            break outerLoop;  // Break outer loop
        }
        console.log(`i=${i}, j=${j}`);
    }
}

continue

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

// Filter while looping
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let num of numbers) {
    if (num % 3 !== 0) {
        continue;  // Skip if not divisible by 3
    }
    console.log(num);  // 3, 6, 9
}

// Skip specific conditions
let users = [
    { name: 'John', active: true },
    { name: 'Jane', active: false },
    { name: 'Bob', active: true }
];

for (let user of users) {
    if (!user.active) {
        continue;  // Skip inactive users
    }
    console.log(user.name);  // John, Bob
}

Labels

// Named loops for break/continue
outer: for (let i = 0; i < 3; i++) {
    inner: for (let j = 0; j < 3; j++) {
        if (i === 1 && j === 1) {
            break outer;  // Break outer loop
        }
        console.log(`i=${i}, j=${j}`);
    }
}

// Continue outer loop
outer: for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (j === 1) {
            continue outer;  // Continue outer loop
        }
        console.log(`i=${i}, j=${j}`);
    }
}

💡 Practical Examples

Input Validation

function validateEmail(email) {
    // Check if empty
    if (!email) {
        return 'Email is required';
    }
    
    // Check if contains @
    if (!email.includes('@')) {
        return 'Email must contain @';
    }
    
    // Check if @ is not at start or end
    if (email.startsWith('@') || email.endsWith('@')) {
        return 'Invalid @ position';
    }
    
    return 'Valid';
}

console.log(validateEmail('user@example.com'));  // 'Valid'
console.log(validateEmail(''));                  // 'Email is required'
console.log(validateEmail('userexample.com'));   // 'Email must contain @'

Array Processing

// Find sum of array
function sumArray(arr) {
    let sum = 0;
    for (let num of arr) {
        sum += num;
    }
    return sum;
}

console.log(sumArray([1, 2, 3, 4, 5]));  // 15

// Find maximum value
function findMax(arr) {
    if (arr.length === 0) return null;
    
    let max = arr[0];
    for (let i = 1; i < arr.length; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

console.log(findMax([3, 7, 2, 9, 1]));  // 9

// Count occurrences
function countOccurrences(arr, target) {
    let count = 0;
    for (let item of arr) {
        if (item === target) {
            count++;
        }
    }
    return count;
}

console.log(countOccurrences([1, 2, 3, 2, 4, 2], 2));  // 3

Pattern Printing

// Print triangle
function printTriangle(rows) {
    for (let i = 1; i <= rows; i++) {
        let line = '';
        for (let j = 1; j <= i; j++) {
            line += '* ';
        }
        console.log(line);
    }
}

printTriangle(5);
// *
// * *
// * * *
// * * * *
// * * * * *

// Print multiplication table
function multiplicationTable(num) {
    for (let i = 1; i <= 10; i++) {
        console.log(`${num} × ${i} = ${num * i}`);
    }
}

multiplicationTable(5);

// Print prime numbers
function printPrimes(max) {
    for (let num = 2; num <= max; num++) {
        let isPrime = true;
        
        for (let divisor = 2; divisor < num; divisor++) {
            if (num % divisor === 0) {
                isPrime = false;
                break;
            }
        }
        
        if (isPrime) {
            console.log(num);
        }
    }
}

printPrimes(20);  // 2, 3, 5, 7, 11, 13, 17, 19

Game Logic

// Number guessing game
function guessingGame() {
    const secret = Math.floor(Math.random() * 100) + 1;
    let attempts = 0;
    let guessed = false;
    
    while (!guessed && attempts < 10) {
        let guess = parseInt(prompt('Guess a number (1-100):'));
        attempts++;
        
        if (guess === secret) {
            console.log(`Correct! You won in ${attempts} attempts`);
            guessed = true;
        } else if (guess < secret) {
            console.log('Too low!');
        } else {
            console.log('Too high!');
        }
    }
    
    if (!guessed) {
        console.log(`Game over! The number was ${secret}`);
    }
}

// Rock, Paper, Scissors
function rockPaperScissors(userChoice) {
    const choices = ['rock', 'paper', 'scissors'];
    const computerChoice = choices[Math.floor(Math.random() * 3)];
    
    if (userChoice === computerChoice) {
        return 'Tie!';
    }
    
    if (
        (userChoice === 'rock' && computerChoice === 'scissors') ||
        (userChoice === 'paper' && computerChoice === 'rock') ||
        (userChoice === 'scissors' && computerChoice === 'paper')
    ) {
        return `You win! ${userChoice} beats ${computerChoice}`;
    }
    
    return `You lose! ${computerChoice} beats ${userChoice}`;
}

console.log(rockPaperScissors('rock'));

Data Filtering

// Filter array based on condition
function filterByAge(users, minAge) {
    let result = [];
    
    for (let user of users) {
        if (user.age >= minAge) {
            result.push(user);
        }
    }
    
    return result;
}

let users = [
    { name: 'John', age: 25 },
    { name: 'Jane', age: 17 },
    { name: 'Bob', age: 30 }
];

console.log(filterByAge(users, 18));
// [{ name: 'John', age: 25 }, { name: 'Bob', age: 30 }]

// Search in array of objects
function searchUsers(users, searchTerm) {
    let results = [];
    
    for (let user of users) {
        if (user.name.toLowerCase().includes(searchTerm.toLowerCase())) {
            results.push(user);
        }
    }
    
    return results;
}

console.log(searchUsers(users, 'jo'));  // [{ name: 'John', age: 25 }]

🎯 Key Takeaways