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
- if/else: Execute code based on conditions, use else if for multiple conditions
- switch: Better than multiple if/else for comparing one value against many
- for loop: Use when you know the number of iterations
- while loop: Use when iterations depend on a condition
- for...of: Modern way to iterate over arrays and iterables
- for...in: Iterate over object properties (use with caution)
- break: Exit loop immediately, continue skips to next iteration
- Truthy/Falsy: Understand which values evaluate to true/false in conditions