JavaScript Control Structures
Master Conditional Statements and Loops to Control Program Flow
Introduction to Control Structures
Control structures are the brain of your JavaScript programs. They allow you to make decisions, repeat actions, and control the flow of execution. Mastering these concepts is essential for creating dynamic, interactive web applications that respond to different conditions and user inputs.
Why Control Structures Matter
Without control structures, your programs would execute line by line from top to bottom. Control structures give you the power to create intelligent programs that can make decisions, repeat tasks, and adapt to different situations—just like a human brain processes information.
What You'll Master
- All types of conditional statements (if, else, switch, ternary)
- Different loop types (for, while, do-while, for-in, for-of)
- Jump statements (break, continue, return)
- Best practices and common pitfalls
- Real-world applications and interactive examples
Quick Interactive Demo
// Control structures in action
const age = 25;
const hasLicense = true;
// Conditional statement
if (age >= 18 && hasLicense) {
console.log("You can drive! 🚗");
} else {
console.log("Sorry, you cannot drive yet.");
}
// Loop example
console.log("\nCounting from 1 to 5:");
for (let i = 1; i <= 5; i++) {
console.log(`Count: ${i}`);
}
// Switch statement
const day = "Monday";
switch (day) {
case "Monday":
console.log("\nStart of the work week!");
break;
case "Friday":
console.log("Almost weekend!");
break;
default:
console.log("Have a great day!");
}
What are Control Structures?
Control structures are programmatic constructs that determine how your code executes. They provide mechanisms for making decisions, repeating code blocks, and changing the flow of execution based on specific conditions. JavaScript offers three primary categories:
- Conditional Statements: Make decisions based on conditions
- Looping Statements: Repeat code blocks multiple times
- Jumping Statements: Alter normal execution flow
Conditional Statements
Conditional statements allow your code to make decisions based on different conditions. They execute specific code blocks only when defined conditions are met, enabling your programs to respond intelligently to various inputs and situations.
Basic Conditional Flow
if Statement
The most basic conditional statement. It executes a block of code if the specified condition is true.
if Statement
Executes code only when the condition evaluates to true. If the condition is false, the code block is skipped entirely.
if (condition) {
// code to execute if true
}
if Statement Demo
// Basic if statement examples
const temperature = 25;
if (temperature > 30) {
console.log("It's hot outside! 🌡️");
}
if (temperature < 20) {
console.log("It's cold outside! 🥶");
}
if (temperature >= 20 && temperature <= 30) {
console.log("Perfect weather! 😊");
}
// Checking user input
const userAge = 18;
if (userAge >= 18) {
console.log("You are an adult.");
}
// Multiple conditions
const hasTicket = true;
const hasID = true;
if (hasTicket && hasID) {
console.log("You can enter the concert! 🎵");
}
if-else Statement
Provides an alternative path when the condition is false, ensuring one of two code blocks always executes.
if-else Statement
Executes the first code block if the condition is true, otherwise executes the second code block. One of the two branches will always run.
if (condition) {
// code if true
} else {
// code if false
}
if-else Statement Demo
// if-else statement examples
const score = 85;
if (score >= 60) {
console.log("You passed! ✅");
} else {
console.log("You failed. ❌");
}
// Checking even or odd
const number = 7;
if (number % 2 === 0) {
console.log(`${number} is even.`);
} else {
console.log(`${number} is odd.`);
}
// User authentication
const isLoggedIn = false;
if (isLoggedIn) {
console.log("Welcome back, user! 👋");
} else {
console.log("Please log in to continue.");
}
// Time-based greeting
const hour = new Date().getHours();
if (hour < 12) {
console.log("Good morning! 🌅");
} else {
console.log("Good afternoon! ☀️");
}
else-if Statement
Allows you to check multiple conditions in sequence, providing more than two possible execution paths.
else-if Statement
Checks multiple conditions in order. The first condition that evaluates to true determines which code block executes. If none are true, the else block runs (if provided).
if (condition1) {
// code if condition1 is true
} else if (condition2) {
// code if condition2 is true
} else {
// code if none are true
}
else-if Statement Demo
// else-if statement examples
const grade = 85;
if (grade >= 90) {
console.log("Grade: A 🏆");
} else if (grade >= 80) {
console.log("Grade: B 📚");
} else if (grade >= 70) {
console.log("Grade: C 📖");
} else if (grade >= 60) {
console.log("Grade: D 📄");
} else {
console.log("Grade: F 😞");
}
// Weather conditions
const temperature = 25;
if (temperature >= 30) {
console.log("It's hot! Wear light clothes. 🌡️");
} else if (temperature >= 20) {
console.log("Perfect weather! Enjoy outdoors. 😊");
} else if (temperature >= 10) {
console.log("It's cool. Bring a jacket. 🧥");
} else {
console.log("It's cold! Bundle up warmly. 🧤");
}
// Traffic light system
const lightColor = "yellow";
if (lightColor === "green") {
console.log("Go! 🟢");
} else if (lightColor === "yellow") {
console.log("Caution! 🟡");
} else if (lightColor === "red") {
console.log("Stop! 🔴");
} else {
console.log("Invalid light color.");
}
// Age categories
const personAge = 25;
if (personAge < 13) {
console.log("Child 👶");
} else if (personAge < 20) {
console.log("Teenager 🧑");
} else if (personAge < 65) {
console.log("Adult 👨");
} else {
console.log("Senior 👴");
}
switch Statement
Provides a cleaner way to handle multiple conditions based on the value of a single expression.
switch Statement
Compares an expression against multiple case values. When a match is found, the corresponding code block executes. More readable than multiple if-else statements for certain scenarios.
switch (expression) {
case value1:
// code
break;
case value2:
// code
break;
default:
// default code
}
switch Statement Demo
// switch statement examples
const dayOfWeek = "Monday";
switch (dayOfWeek) {
case "Monday":
console.log("Start of the work week! 💼");
break;
case "Tuesday":
console.log("Second day of the week.");
break;
case "Wednesday":
console.log("Hump day! 🐪");
break;
case "Thursday":
console.log("Almost Friday!");
break;
case "Friday":
console.log("TGIF! 🎉");
break;
case "Saturday":
case "Sunday":
console.log("Weekend! 🎊");
break;
default:
console.log("Invalid day.");
}
// Menu system
const choice = 2;
switch (choice) {
case 1:
console.log("You selected: View Profile 👤");
break;
case 2:
console.log("You selected: Edit Settings ⚙️");
break;
case 3:
console.log("You selected: Logout 🚪");
break;
default:
console.log("Invalid choice.");
}
// Grade calculator with switch
const score = 85;
let grade;
if (score >= 90) grade = "A";
else if (score >= 80) grade = "B";
else if (score >= 70) grade = "C";
else if (score >= 60) grade = "D";
else grade = "F";
switch (grade) {
case "A":
case "B":
console.log("Excellent work! 🌟");
break;
case "C":
console.log("Good job! 👍");
break;
case "D":
console.log("You passed. 📄");
break;
case "F":
console.log("Needs improvement. 📚");
break;
}
Ternary Operator
A concise way to write simple if-else statements in a single line. Perfect for simple conditional assignments.
Ternary Operator
A shorthand way to write simple if-else statements. Syntax: condition ? valueIfTrue : valueIfFalse. Best used for simple conditional assignments, not complex logic.
condition ? valueIfTrue : valueIfFalse
Ternary Operator Demo
// Ternary operator examples
const age = 20;
const canVote = age >= 18 ? "Yes" : "No";
console.log(`Can vote: ${canVote}`);
// Simple greeting
const hour = new Date().getHours();
const greeting = hour < 12 ? "Good morning!" : "Good afternoon!";
console.log(greeting);
// Setting default values
const userName = "";
const displayName = userName ? userName : "Guest";
console.log(`Welcome, ${displayName}!`);
// Chaining ternary operators
const score = 85;
const grade = score >= 90 ? "A" :
score >= 80 ? "B" :
score >= 70 ? "C" :
score >= 60 ? "D" : "F";
console.log(`Grade: ${grade}`);
// Ternary with functions
const isEven = (num) => num % 2 === 0 ? "Even" : "Odd";
console.log(`7 is ${isEven(7)}`);
console.log(`8 is ${isEven(8)}`);
// Array filtering with ternary
const numbers = [1, 2, 3, 4, 5];
const result = numbers.map(n => n > 3 ? `${n} is large` : `${n} is small`);
console.log("Number analysis:", result);
Looping Statements
Loops allow you to repeat code blocks multiple times. They're essential for iterating through arrays, processing data, and automating repetitive tasks. JavaScript provides several types of loops, each suited for different scenarios.
Generic Loop Flow
for Loop
The most common loop type. Executes a block of code a specific number of times with precise control.
for Loop
Repeats code a specific number of times. Best for iterating when you know the exact number of iterations needed. Consists of initialization, condition, and increment/decrement.
for (initialization; condition; increment) {
// code to repeat
}
for Loop Demo
// Basic for loop examples
console.log("=== BASIC FOR LOOPS ===");
// Counting from 1 to 5
console.log("Counting from 1 to 5:");
for (let i = 1; i <= 5; i++) {
console.log(`Count: ${i}`);
}
// Counting backwards
console.log("\nCounting backwards from 5 to 1:");
for (let i = 5; i >= 1; i--) {
console.log(`Count: ${i}`);
}
// Even numbers
console.log("\nEven numbers from 2 to 10:");
for (let i = 2; i <= 10; i += 2) {
console.log(`Even: ${i}`);
}
// Array iteration
console.log("\n=== ARRAY ITERATION ===");
const fruits = ["apple", "banana", "orange", "grape"];
console.log("Fruits in the basket:");
for (let i = 0; i < fruits.length; i++) {
console.log(`${i + 1}. ${fruits[i]}`);
}
// Calculating sum
console.log("\n=== CALCULATIONS ===");
const numbers = [3, 7, 2, 9, 5];
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
console.log(`Numbers: [${numbers}]`);
console.log(`Sum: ${sum}`);
console.log(`Average: ${sum / numbers.length}`);
// Multiplication table
console.log("\n=== 5 TIMES TABLE ===");
for (let i = 1; i <= 10; i++) {
console.log(`5 × ${i} = ${5 * i}`);
}
// Nested loops
console.log("\n=== PATTERN WITH NESTED LOOPS ===");
for (let i = 1; i <= 3; i++) {
let pattern = "";
for (let j = 1; j <= i; j++) {
pattern += "* ";
}
console.log(pattern);
}
while Loop
Executes code as long as a condition remains true. Perfect when you don't know the exact number of iterations.
while Loop
Repeats code while a condition is true. The condition is checked before each iteration. If the condition starts as false, the loop never executes.
while (condition) {
// code to repeat
// condition update
}
while Loop Demo
// Basic while loop examples
console.log("=== BASIC WHILE LOOPS ===");
// Counting with while
let count = 1;
console.log("Counting from 1 to 5:");
while (count <= 5) {
console.log(`Count: ${count}`);
count++;
}
// User input simulation
console.log("\n=== GUESSING GAME ===");
const targetNumber = 7;
let guess = Math.floor(Math.random() * 10) + 1;
let attempts = 1;
console.log(`Target number: ${targetNumber}`);
console.log("Starting guesses...");
while (guess !== targetNumber) {
console.log(`Guess ${attempts}: ${guess} - Wrong!`);
guess = Math.floor(Math.random() * 10) + 1;
attempts++;
}
console.log(`Guess ${attempts}: ${guess} - Correct! 🎉`);
console.log(`It took ${attempts} attempts.`);
// Factorial calculation
console.log("\n=== FACTORIAL CALCULATION ===");
const number = 5;
let factorial = 1;
let i = 1;
while (i <= number) {
factorial *= i;
i++;
}
console.log(`${number}! = ${factorial}`);
// Array processing
console.log("\n=== ARRAY PROCESSING ===");
const temperatures = [22, 28, 31, 25, 30, 27, 29];
let index = 0;
let hotDays = 0;
console.log("Checking for hot days (≥30°C):");
while (index < temperatures.length) {
if (temperatures[index] >= 30) {
console.log(`Day ${index + 1}: ${temperatures[index]}°C - Hot! 🌡️`);
hotDays++;
}
index++;
}
console.log(`Total hot days: ${hotDays}`);
// Infinite loop prevention
console.log("\n=== SAFE INFINITE LOOP ===");
let counter = 0;
const maxIterations = 10;
while (counter < maxIterations) {
console.log(`Iteration: ${counter + 1}`);
counter++;
if (counter === 5) {
console.log("Halfway there!");
}
}
console.log("Loop completed safely!");
do-while Loop
Similar to while loop, but guarantees at least one execution since the condition is checked after the code block.
do-while Loop
Executes the code block once, then repeats as long as the condition is true. Guarantees at least one execution regardless of the initial condition.
do {
// code to repeat
// condition update
} while (condition);
do-while Loop Demo
// do-while loop examples
console.log("=== DO-WHILE LOOPS ===");
// Basic do-while - executes at least once
let num = 5;
console.log("Basic do-while (num starts at 5, condition is num < 5):");
do {
console.log(`Number: ${num}`);
num++;
} while (num < 5);
console.log("Loop executed once even though condition was false!");
// Menu system simulation
console.log("\n=== MENU SYSTEM ===");
let choice;
let isRunning = true;
console.log("Welcome to the Number Game!");
do {
// Simulate user choice
choice = Math.floor(Math.random() * 4) + 1;
switch (choice) {
case 1:
console.log("You chose: Play Game 🎮");
break;
case 2:
console.log("You chose: View Scores 📊");
break;
case 3:
console.log("You chose: Settings ⚙️");
break;
case 4:
console.log("You chose: Exit 🚪");
isRunning = false;
break;
}
} while (isRunning);
console.log("Thanks for playing!");
// Input validation
console.log("\n=== INPUT VALIDATION ===");
let userInput;
let attempts = 0;
do {
// Simulate user input
userInput = Math.floor(Math.random() * 10) + 1;
attempts++;
console.log(`Attempt ${attempts}: Input = ${userInput}`);
if (userInput < 1 || userInput > 5) {
console.log("Please enter a number between 1 and 5.");
}
} while (userInput < 1 || userInput > 5);
console.log(`Valid input received: ${userInput} ✅`);
// Password attempt simulation
console.log("\n=== PASSWORD ATTEMPTS ===");
const correctPassword = "secret123";
let passwordAttempts = 0;
let maxAttempts = 3;
let enteredPassword;
do {
passwordAttempts++;
// Simulate password entry
enteredPassword = passwordAttempts === 1 ? "wrongpass" :
passwordAttempts === 2 ? "anotherwrong" :
correctPassword;
console.log(`Attempt ${passwordAttempts}: Password entered`);
if (enteredPassword === correctPassword) {
console.log("Access granted! 🔓");
break;
} else if (passwordAttempts < maxAttempts) {
console.log("Wrong password. Try again.");
}
} while (passwordAttempts < maxAttempts);
if (enteredPassword !== correctPassword) {
console.log("Maximum attempts reached. Access denied! 🔒");
}
// Number guessing with do-while
console.log("\n=== NUMBER GUESSING GAME ===");
const secretNumber = Math.floor(Math.random() * 10) + 1;
let guess;
let guessCount = 0;
console.log("I'm thinking of a number between 1 and 10...");
do {
guessCount++;
guess = Math.floor(Math.random() * 10) + 1; // Simulate guesses
console.log(`Guess ${guessCount}: ${guess}`);
if (guess < secretNumber) {
console.log("Too low! 📉");
} else if (guess > secretNumber) {
console.log("Too high! 📈");
}
} while (guess !== secretNumber);
console.log(`🎉 Congratulations! You guessed it in ${guessCount} attempts!`);
console.log(`The secret number was: ${secretNumber}`);
for-in Loop
Iterates over enumerable properties of objects. Perfect for looping through object keys.
for-in Loop
Iterates over all enumerable properties of an object, including inherited ones. Returns property names (keys) one by one. Best for object property enumeration.
for (variable in object) {
// code to execute
}
for-in Loop Demo
// for-in loop examples
console.log("=== FOR-IN LOOPS ===");
// Object property iteration
const person = {
name: "John Doe",
age: 30,
city: "New York",
profession: "Developer"
};
console.log("Person object properties:");
for (let key in person) {
console.log(`${key}: ${person[key]}`);
}
// Array iteration (not recommended - use for-of instead)
console.log("\n=== ARRAY WITH FOR-IN (for demonstration) ===");
const colors = ["red", "green", "blue"];
console.log("Array indices:");
for (let index in colors) {
console.log(`Index ${index}: ${colors[index]}`);
}
// Nested object properties
const company = {
name: "Tech Corp",
employees: 150,
departments: {
development: 50,
marketing: 30,
sales: 70
},
locations: ["New York", "London", "Tokyo"]
};
console.log("\n=== NESTED OBJECT ===");
console.log("Company information:");
for (let key in company) {
if (typeof company[key] === 'object' && !Array.isArray(company[key])) {
console.log(`${key}:`);
for (let subKey in company[key]) {
console.log(` ${subKey}: ${company[key][subKey]}`);
}
} else {
console.log(`${key}: ${company[key]}`);
}
}
// Checking object properties
console.log("\n=== PROPERTY CHECKS ===");
const car = {
brand: "Toyota",
model: "Camry",
year: 2022
};
console.log("Car properties:");
for (let prop in car) {
if (car.hasOwnProperty(prop)) {
console.log(`Own property: ${prop} = ${car[prop]}`);
}
}
// Dynamic property access
console.log("\n=== DYNAMIC PROPERTY ACCESS ===");
const student = {
id: 101,
name: "Alice",
grades: {
math: 95,
english: 88,
science: 92
}
};
console.log("Student summary:");
let total = 0;
let subjectCount = 0;
for (let subject in student.grades) {
total += student.grades[subject];
subjectCount++;
console.log(`${subject}: ${student.grades[subject]}`);
}
console.log(`Average grade: ${(total / subjectCount).toFixed(2)}`);
// Object method iteration
console.log("\n=== OBJECT WITH METHODS ===");
const calculator = {
value: 0,
add: function(num) { this.value += num; },
subtract: function(num) { this.value -= num; },
multiply: function(num) { this.value *= num; },
getValue: function() { return this.value; }
};
console.log("Calculator methods:");
for (let method in calculator) {
if (typeof calculator[method] === 'function') {
console.log(`Method: ${method}`);
} else {
console.log(`Property: ${method} = ${calculator[method]}`);
}
}
for-of Loop
Iterates over iterable objects (arrays, strings, maps, sets). The modern way to loop through arrays.
for-of Loop
Iterates over values of iterable objects (arrays, strings, maps, sets, etc.). Returns actual values, not indices. The modern, preferred way to iterate over arrays.
for (variable of iterable) {
// code to execute
}
for-of Loop Demo
// for-of loop examples
console.log("=== FOR-OF LOOPS ===");
// Array iteration - the modern way
const fruits = ["apple", "banana", "orange", "grape", "kiwi"];
console.log("Fruits in the basket:");
for (const fruit of fruits) {
console.log(`🍎 ${fruit}`);
}
// String iteration
console.log("\n=== STRING ITERATION ===");
const message = "Hello";
console.log("Characters in 'Hello':");
for (const char of message) {
console.log(`Character: ${char}`);
}
// Array with index using entries()
console.log("\n=== ARRAY WITH INDEX ===");
const colors = ["red", "green", "blue", "yellow"];
console.log("Colors with indices:");
for (const [index, color] of colors.entries()) {
console.log(`${index}: ${color}`);
}
// Array of objects
console.log("\n=== ARRAY OF OBJECTS ===");
const students = [
{ name: "Alice", grade: 95 },
{ name: "Bob", grade: 87 },
{ name: "Charlie", grade: 92 }
];
console.log("Student grades:");
for (const student of students) {
console.log(`${student.name}: ${student.grade}`);
}
// Array filtering with for-of
console.log("\n=== FILTERING WITH FOR-OF ===");
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let evenNumbers = [];
let oddNumbers = [];
for (const num of numbers) {
if (num % 2 === 0) {
evenNumbers.push(num);
} else {
oddNumbers.push(num);
}
}
console.log(`Original: [${numbers}]`);
console.log(`Even numbers: [${evenNumbers}]`);
console.log(`Odd numbers: [${oddNumbers}]`);
// Finding maximum value
console.log("\n=== FINDING MAXIMUM ===");
const scores = [85, 92, 78, 95, 88];
let maxScore = scores[0];
for (const score of scores) {
if (score > maxScore) {
maxScore = score;
}
}
console.log(`Scores: [${scores}]`);
console.log(`Maximum score: ${maxScore}`);
// Array transformation
console.log("\n=== ARRAY TRANSFORMATION ===");
const prices = [10.99, 5.50, 8.75, 12.25];
const taxRate = 0.08;
const pricesWithTax = [];
for (const price of prices) {
const priceWithTax = price * (1 + taxRate);
pricesWithTax.push(priceWithTax);
}
console.log(`Original prices: [${prices.map(p => `$${p.toFixed(2)}`)}]`);
console.log(`Prices with tax: [${pricesWithTax.map(p => `$${p.toFixed(2)}`)}]`);
// Set iteration
console.log("\n=== SET ITERATION ===");
const uniqueNumbers = new Set([1, 2, 3, 4, 5]);
console.log("Unique numbers in set:");
for (const num of uniqueNumbers) {
console.log(`Number: ${num}`);
}
// Map iteration
console.log("\n=== MAP ITERATION ===");
const userRoles = new Map([
["alice", "admin"],
["bob", "user"],
["charlie", "moderator"]
]);
console.log("User roles:");
for (const [username, role] of userRoles) {
console.log(`${username}: ${role}`);
}
// Break and continue with for-of
console.log("\n=== BREAK AND CONTINUE ===");
const values = [1, -2, 3, -4, 5, -6, 7];
console.log("Processing positive numbers:");
for (const value of values) {
if (value < 0) {
console.log(`Skipping negative number: ${value}`);
continue;
}
if (value > 5) {
console.log(`Stopping at number > 5: ${value}`);
break;
}
console.log(`Processing: ${value}`);
}
Jump Statements
Jump statements allow you to alter the normal flow of loops and switch statements. They provide fine-grained control over when to exit loops early or skip iterations.
break Statement
Immediately exits the current loop or switch statement. Use when you need to terminate a loop early based on a specific condition.
break; // exits current loop
continue Statement
Skips the rest of the current iteration and moves to the next one. Use to skip certain iterations without exiting the entire loop.
continue; // skip to next iteration
return Statement
Exits the current function and returns a value. In loops within functions, it exits both the loop and the function.
return value; // exit function with value
Jump Statements Demo
// Jump statements examples
console.log("=== BREAK STATEMENT ===");
// break in for loop
console.log("Finding first even number:");
for (let i = 1; i <= 10; i++) {
if (i % 2 === 0) {
console.log(`First even number: ${i}`);
break; // Exit loop immediately
}
}
// break in while loop
console.log("\nSearching for specific value:");
let searchArray = [3, 7, 2, 9, 5, 8, 1];
let target = 5;
let foundIndex = -1;
for (let i = 0; i < searchArray.length; i++) {
if (searchArray[i] === target) {
foundIndex = i;
break; // Stop searching once found
}
}
console.log(`Array: [${searchArray}]`);
console.log(`Target: ${target}`);
console.log(`Found at index: ${foundIndex}`);
// break in nested loops
console.log("\nBreak in nested loops:");
for (let i = 1; i <= 3; i++) {
console.log(`Outer loop: ${i}`);
for (let j = 1; j <= 3; j++) {
if (j === 2) break; // Breaks inner loop only
console.log(` Inner loop: ${j}`);
}
}
console.log("\n=== CONTINUE STATEMENT ===");
// continue in for loop
console.log("Printing only odd numbers:");
for (let i = 1; i <= 10; i++) {
if (i % 2 === 0) continue; // Skip even numbers
console.log(`Odd number: ${i}`);
}
// continue in while loop
console.log("\nProcessing positive numbers:");
let numbers = [3, -1, 7, -5, 9, -2, 4];
let positiveSum = 0;
for (let num of numbers) {
if (num < 0) {
console.log(`Skipping negative: ${num}`);
continue;
}
positiveSum += num;
console.log(`Adding positive: ${num}`);
}
console.log(`Array: [${numbers}]`);
console.log(`Sum of positive numbers: ${positiveSum}`);
// continue with labels (advanced)
console.log("\n=== LABELED CONTINUE ===");
outerLoop: for (let i = 1; i <= 3; i++) {
console.log(`Outer: ${i}`);
for (let j = 1; j <= 3; j++) {
if (j === 2) continue outerLoop; // Continue outer loop
console.log(` Inner: ${j}`);
}
}
console.log("\n=== RETURN STATEMENT ===");
// Function with early return
function findFirstPositive(numbers) {
for (let num of numbers) {
if (num > 0) {
return num; // Return immediately, exiting function
}
}
return null; // Return null if no positive found
}
const testNumbers = [-5, -2, 0, 3, 7, -1];
const firstPositive = findFirstPositive(testNumbers);
console.log(`Numbers: [${testNumbers}]`);
console.log(`First positive: ${firstPositive}`);
// Function with loop and condition
function processUntilNegative(numbers) {
let sum = 0;
for (let num of numbers) {
if (num < 0) {
console.log(`Stopping at negative: ${num}`);
return sum; // Return sum and exit function
}
sum += num;
console.log(`Adding: ${num}, Sum: ${sum}`);
}
return sum;
}
const mixedNumbers = [1, 3, 5, -2, 4, 6];
const result = processUntilNegative(mixedNumbers);
console.log(`Final result: ${result}`);
// Practical example: Password validation
function validatePassword(password) {
if (password.length < 8) {
return "Password too short";
}
let hasNumber = false;
let hasUpper = false;
let hasLower = false;
for (let char of password) {
if (!isNaN(char)) hasNumber = true;
if (char === char.toUpperCase() && isNaN(char)) hasUpper = true;
if (char === char.toLowerCase() && isNaN(char)) hasLower = true;
// Early return if all conditions met
if (hasNumber && hasUpper && hasLower) {
return "Password is valid ✅";
}
}
return "Password needs number, uppercase, and lowercase letters";
}
const testPasswords = ["short", "longenough", "Longenough1", "LongEnough1"];
for (let pwd of testPasswords) {
console.log(`\nPassword: "${pwd}"`);
console.log(validatePassword(pwd));
}
Best Practices & Common Pitfalls
Following best practices in control structures helps you write cleaner, more maintainable, and bug-free code. Here are the most important guidelines for using conditional statements and loops effectively.
Use const and let
Always use const for variables that won't be reassigned, and let for those that will. Avoid using var in modern JavaScript code.
const MAX_ATTEMPTS = 3;
let currentAttempt = 0;
Avoid Deep Nesting
Avoid deeply nested if-else statements. Use early returns or switch statements when appropriate to improve readability.
if (condition1) {
if (condition2) {
if (condition3) {
// too deep!
Always Use break in switch
Always include break statements in switch cases to prevent fall-through behavior unless it's intentional.
case "value":
// code
break; // Don't forget!
Use Descriptive Names
Choose meaningful variable names that clearly indicate their purpose. This makes your code self-documenting and easier to understand.
const userAge = 25;
const isUserActive = true;
const maximumLoginAttempts = 3;
Common Pitfalls to Avoid
- Infinite Loops: Always ensure your loop conditions will eventually become false
- Off-by-One Errors: Be careful with loop boundaries (i < length vs i <= length)
- Assignment vs Comparison: Use === instead of ==, and don't confuse = with ==
- Missing break in switch: This causes fall-through behavior
- Modifying loop variables: Be cautious when modifying the loop counter inside the loop
Best Practices Validator
// Best Practices Examples
console.log("=== BEST PRACTICES DEMONSTRATION ===");
// 1. Use const and let appropriately
const MAX_ATTEMPTS = 5;
const API_ENDPOINT = "https://api.example.com";
let currentAttempt = 0;
let isProcessing = false;
console.log("Constants:", { MAX_ATTEMPTS, API_ENDPOINT });
console.log("Variables:", { currentAttempt, isProcessing });
// 2. Use descriptive names
const calculateUserAge = (birthYear) => {
const currentYear = new Date().getFullYear();
return currentYear - birthYear;
};
const userBirthYear = 1995;
const userAge = calculateUserAge(userBirthYear);
console.log(`User age: ${userAge}`);
// 3. Avoid deep nesting with early returns
const validateUserInput = (input) => {
if (!input) return "Input is required";
if (input.length < 3) return "Input too short";
if (input.length > 50) return "Input too long";
if (!/^[a-zA-Z0-9]+$/.test(input)) return "Invalid characters";
return "Input is valid";
};
const testInputs = ["", "ab", "valid_input", "this_is_way_too_long_for_validation", "invalid@chars"];
testInputs.forEach(input => {
console.log(`Input: "${input}" - ${validateUserInput(input)}`);
});
// 4. Use switch for multiple conditions
const getDayType = (day) => {
switch (day.toLowerCase()) {
case "monday":
case "tuesday":
case "wednesday":
case "thursday":
case "friday":
return "Weekday 💼";
case "saturday":
case "sunday":
return "Weekend 🎉";
default:
return "Invalid day";
}
};
const days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "InvalidDay"];
days.forEach(day => {
console.log(`${day}: ${getDayType(day)}`);
});
// 5. Use for-of for arrays instead of for-in
const scores = [85, 92, 78, 95, 88];
let total = 0;
console.log("\nProcessing scores with for-of:");
for (const score of scores) {
total += score;
console.log(`Score: ${score}`);
}
const average = total / scores.length;
console.log(`Total: ${total}, Average: ${average}`);
// 6. Always use break in switch statements
const getUserRole = (role) => {
switch (role) {
case "admin":
return "Administrator with full access";
case "moderator":
return "Moderator with content management access";
case "user":
return "Standard user with basic access";
default:
return "Guest with limited access";
}
};
const roles = ["admin", "user", "moderator", "guest"];
roles.forEach(role => {
console.log(`Role "${role}": ${getUserRole(role)}`);
});
// 7. Avoid infinite loops with proper conditions
const safeCounter = (maxCount) => {
let count = 0;
const results = [];
while (count < maxCount) {
results.push(count);
count++; // Proper increment to avoid infinite loop
}
return results;
};
console.log("\nSafe counter:", safeCounter(5));
// 8. Use ternary for simple conditions
const temperature = 25;
const weatherAdvice = temperature > 30 ? "Stay hydrated! 💧" :
temperature < 10 ? "Bundle up! 🧥" :
"Perfect weather! 😊";
console.log(`Temperature: ${temperature}°C - ${weatherAdvice}`);
// 9. Handle null and undefined properly
const processUserData = (data) => {
if (!data) return "No data provided";
if (data.length === 0) return "Empty data";
return `Processing ${data.length} items`;
};
const dataSets = [null, undefined, [], [1, 2, 3], "invalid"];
dataSets.forEach(data => {
console.log(`Data: ${data} - ${processUserData(data)}`);
});
// 10. Use proper error handling
const divideNumbers = (a, b) => {
if (b === 0) {
return "Error: Division by zero";
}
if (typeof a !== 'number' || typeof b !== 'number') {
return "Error: Invalid input type";
}
return a / b;
};
console.log("\nDivision examples:");
console.log(`10 / 2 = ${divideNumbers(10, 2)}`);
console.log(`10 / 0 = ${divideNumbers(10, 0)}`);
console.log(`10 / "a" = ${divideNumbers(10, "a")}`);
Real-World Examples & Applications
Let's apply everything we've learned with practical, real-world examples that demonstrate how control structures work together in actual JavaScript applications. These examples showcase common patterns you'll encounter in professional development.
E-commerce Shopping Cart
A comprehensive shopping cart system demonstrating conditional statements, loops, and control flow in a real e-commerce application.
Shopping Cart with Discounts & Validation
// E-commerce Shopping Cart System
console.log("=== E-COMMERCE SHOPPING CART SYSTEM ===");
// Product catalog
const products = [
{ id: 1, name: "Laptop", price: 999.99, category: "electronics", stock: 10 },
{ id: 2, name: "Mouse", price: 29.99, category: "accessories", stock: 50 },
{ id: 3, name: "Keyboard", price: 79.99, category: "accessories", stock: 0 },
{ id: 4, name: "Monitor", price: 299.99, category: "electronics", stock: 15 },
{ id: 5, name: "USB Cable", price: 12.99, category: "accessories", stock: 100 }
];
// Shopping cart
const shoppingCart = [
{ productId: 1, quantity: 1 },
{ productId: 2, quantity: 2 },
{ productId: 4, quantity: 1 },
{ productId: 5, quantity: 3 }
];
// Customer information
const customer = {
type: "premium", // regular, premium, student, senior
isLoyaltyMember: true,
couponCode: "SAVE20"
};
// Tax and discount configuration
const CONFIG = {
TAX_RATE: 0.08,
DISCOUNTS: {
premium: 0.15,
student: 0.10,
senior: 0.12,
loyalty: 0.05,
bulk: 0.08
},
BULK_THRESHOLD: 500,
FREE_SHIPPING_THRESHOLD: 100
};
// Helper functions
const getProductById = (productId) => {
return products.find(product => product.id === productId);
};
const validateCart = (cart) => {
const errors = [];
for (const item of cart) {
const product = getProductById(item.productId);
if (!product) {
errors.push(`Product ID ${item.productId} not found`);
continue;
}
if (item.quantity <= 0) {
errors.push(`Invalid quantity for ${product.name}`);
}
if (product.stock < item.quantity) {
errors.push(`Insufficient stock for ${product.name}`);
}
}
return errors;
};
const calculateSubtotal = (cart) => {
let subtotal = 0;
for (const item of cart) {
const product = getProductById(item.productId);
if (product) {
subtotal += product.price * item.quantity;
}
}
return subtotal;
};
const applyDiscounts = (subtotal, customer) => {
let totalDiscount = 0;
const appliedDiscounts = [];
// Customer type discount
if (CONFIG.DISCOUNTS[customer.type]) {
const discount = subtotal * CONFIG.DISCOUNTS[customer.type];
totalDiscount += discount;
appliedDiscounts.push({
type: customer.type,
percentage: CONFIG.DISCOUNTS[customer.type] * 100,
amount: discount
});
}
// Loyalty discount
if (customer.isLoyaltyMember && customer.type !== "loyalty") {
const discount = subtotal * CONFIG.DISCOUNTS.loyalty;
totalDiscount += discount;
appliedDiscounts.push({
type: "loyalty",
percentage: CONFIG.DISCOUNTS.loyalty * 100,
amount: discount
});
}
// Bulk discount
if (subtotal >= CONFIG.BULK_THRESHOLD) {
const discount = subtotal * CONFIG.DISCOUNTS.bulk;
totalDiscount += discount;
appliedDiscounts.push({
type: "bulk",
percentage: CONFIG.DISCOUNTS.bulk * 100,
amount: discount
});
}
// Coupon validation
if (customer.couponCode) {
switch (customer.couponCode.toUpperCase()) {
case "SAVE20":
const discount = subtotal * 0.20;
totalDiscount += discount;
appliedDiscounts.push({
type: "coupon",
percentage: 20,
amount: discount
});
break;
case "WELCOME10":
const welcomeDiscount = subtotal * 0.10;
totalDiscount += welcomeDiscount;
appliedDiscounts.push({
type: "coupon",
percentage: 10,
amount: welcomeDiscount
});
break;
default:
console.log(`Invalid coupon code: ${customer.couponCode}`);
}
}
return { totalDiscount, appliedDiscounts };
};
const calculateShipping = (subtotal) => {
if (subtotal >= CONFIG.FREE_SHIPPING_THRESHOLD) {
return 0;
}
// Calculate shipping based on cart contents
let totalItems = 0;
let hasLargeItems = false;
for (const item of shoppingCart) {
const product = getProductById(item.productId);
if (product) {
totalItems += item.quantity;
if (product.category === "electronics" && item.quantity > 0) {
hasLargeItems = true;
}
}
}
let shippingCost = 9.99; // Base shipping
if (hasLargeItems) {
shippingCost += 10; // Large item surcharge
}
if (totalItems > 5) {
shippingCost += 5; // Heavy order surcharge
}
return shippingCost;
};
const processOrder = (cart, customer) => {
console.log("🔍 Processing order...");
// Step 1: Validate cart
const validationErrors = validateCart(cart);
if (validationErrors.length > 0) {
console.log("❌ Validation errors:");
for (const error of validationErrors) {
console.log(` - ${error}`);
}
return { success: false, errors: validationErrors };
}
// Step 2: Calculate subtotal
const subtotal = calculateSubtotal(cart);
console.log(`📊 Subtotal: $${subtotal.toFixed(2)}`);
// Step 3: Apply discounts
const { totalDiscount, appliedDiscounts } = applyDiscounts(subtotal, customer);
if (appliedDiscounts.length > 0) {
console.log("🏷️ Applied discounts:");
for (const discount of appliedDiscounts) {
console.log(` - ${discount.type}: ${discount.percentage}% (-$${discount.amount.toFixed(2)})`);
}
console.log(`💰 Total discount: $${totalDiscount.toFixed(2)}`);
}
// Step 4: Calculate discounted total
const discountedTotal = subtotal - totalDiscount;
console.log(`💳 After discounts: $${discountedTotal.toFixed(2)}`);
// Step 5: Calculate shipping
const shippingCost = calculateShipping(discountedTotal);
if (shippingCost === 0) {
console.log("🚚 Free shipping applied!");
} else {
console.log(`🚚 Shipping: $${shippingCost.toFixed(2)}`);
}
// Step 6: Calculate tax
const taxAmount = (discountedTotal + shippingCost) * CONFIG.TAX_RATE;
console.log(`💸 Tax (${(CONFIG.TAX_RATE * 100).toFixed(0)}%): $${taxAmount.toFixed(2)}`);
// Step 7: Final total
const finalTotal = discountedTotal + shippingCost + taxAmount;
console.log(`🎯 FINAL TOTAL: $${finalTotal.toFixed(2)}`);
// Step 8: Generate order summary
const orderSummary = {
items: [],
subtotal,
totalDiscount,
shippingCost,
taxAmount,
finalTotal,
savings: totalDiscount
};
for (const item of cart) {
const product = getProductById(item.productId);
if (product) {
orderSummary.items.push({
name: product.name,
price: product.price,
quantity: item.quantity,
subtotal: product.price * item.quantity
});
}
}
return { success: true, orderSummary };
};
// Run the shopping cart process
console.log("🛒 SHOPPING CART CONTENTS:");
for (const item of shoppingCart) {
const product = getProductById(item.productId);
if (product) {
console.log(` - ${product.name} x${item.quantity} @ $${product.price.toFixed(2)} each`);
}
}
console.log(`\n👤 CUSTOMER INFO:`);
console.log(` Type: ${customer.type}`);
console.log(` Loyalty Member: ${customer.isLoyaltyMember ? 'Yes' : 'No'}`);
console.log(` Coupon: ${customer.couponCode}`);
console.log("\n" + "=".repeat(50));
const result = processOrder(shoppingCart, customer);
if (result.success) {
console.log("\n📋 ORDER SUMMARY:");
console.log("Items:");
for (const item of result.orderSummary.items) {
console.log(` - ${item.name} x${item.quantity} = $${item.subtotal.toFixed(2)}`);
}
console.log(`\nSubtotal: $${result.orderSummary.subtotal.toFixed(2)}`);
console.log(`Discounts: -$${result.orderSummary.totalDiscount.toFixed(2)}`);
console.log(`Shipping: $${result.orderSummary.shippingCost.toFixed(2)}`);
console.log(`Tax: $${result.orderSummary.taxAmount.toFixed(2)}`);
console.log(`TOTAL: $${result.orderSummary.finalTotal.toFixed(2)}`);
console.log(`💰 You saved: $${result.orderSummary.savings.toFixed(2)}!`);
}
Interactive Game Logic
A number guessing game demonstrating complex control flow, user input simulation, and game state management using various control structures.
Number Guessing Game with Levels
// Interactive Number Guessing Game
console.log("=== NUMBER GUESSING GAME WITH LEVELS ===");
console.log("🎮 Welcome to the Ultimate Number Guessing Game!");
// Game configuration
const GAME_CONFIG = {
levels: [
{ name: "Easy", maxNumber: 10, maxAttempts: 5, points: 10 },
{ name: "Medium", maxNumber: 50, maxAttempts: 7, points: 25 },
{ name: "Hard", maxNumber: 100, maxAttempts: 10, points: 50 }
],
bonusThreshold: 3, // attempts for bonus points
bonusMultiplier: 2
};
// Game state
let gameState = {
currentLevel: 0,
score: 0,
totalGames: 0,
wins: 0,
consecutiveWins: 0,
achievements: []
};
// Achievement system
const ACHIEVEMENTS = {
FIRST_WIN: { name: "First Victory", description: "Win your first game" },
CONSECUTIVE_3: { name: "Hot Streak", description: "Win 3 games in a row" },
PERFECT_GAME: { name: "Perfect Game", description: "Win in 1 attempt" },
LEVEL_MASTER: { name: "Level Master", description: "Complete all levels" },
HIGH_SCORER: { name: "High Scorer", description: "Reach 500 points" }
};
// Helper functions
const checkAchievements = () => {
const newAchievements = [];
if (gameState.wins === 1 && !gameState.achievements.includes("FIRST_WIN")) {
newAchievements.push(ACHIEVEMENTS.FIRST_WIN);
gameState.achievements.push("FIRST_WIN");
}
if (gameState.consecutiveWins === 3 && !gameState.achievements.includes("CONSECUTIVE_3")) {
newAchievements.push(ACHIEVEMENTS.CONSECUTIVE_3);
gameState.achievements.push("CONSECUTIVE_3");
}
if (gameState.score >= 500 && !gameState.achievements.includes("HIGH_SCORER")) {
newAchievements.push(ACHIEVEMENTS.HIGH_SCORER);
gameState.achievements.push("HIGH_SCORER");
}
return newAchievements;
};
const getRandomNumber = (max) => {
return Math.floor(Math.random() * max) + 1;
};
const getHint = (guess, target) => {
const difference = Math.abs(guess - target);
if (difference <= 2) {
return guess < target ? "Very close! Try a bit higher." : "Very close! Try a bit lower.";
} else if (difference <= 5) {
return guess < target ? "Getting warmer! Go higher." : "Getting warmer! Go lower.";
} else {
return guess < target ? "Too low! Aim higher." : "Too high! Aim lower.";
}
};
const calculatePoints = (level, attemptsUsed, maxAttempts) => {
let points = level.points;
// Bonus for quick completion
if (attemptsUsed <= GAME_CONFIG.bonusThreshold) {
points *= GAME_CONFIG.bonusMultiplier;
console.log(`🎯 Bonus points for quick completion! (${GAME_CONFIG.bonusMultiplier}x multiplier)`);
}
// Penalty for using many attempts
if (attemptsUsed > maxAttempts * 0.8) {
points = Math.floor(points * 0.8);
console.log("⏰ Point penalty for using many attempts");
}
return points;
};
// Game functions