We use cookies to enhance your experience on the site
CodeWorlds

Loops and Iterations

In Jurassic Park, routine tasks must be performed regularly and repeatedly: checking the fence of every enclosure every hour, monitoring all security cameras, updating the health status of every dinosaur. Performing these tasks manually would be tedious and error-prone.

Similarly in JavaScript, loops allow for the automatic and efficient execution of repetitive operations. Instead of writing the same code multiple times, we can use loops to execute it for many elements or a specified number of times.

The for Loop

The

for
loop is one of the most popular loops in JavaScript. It consists of three parts: initialization, condition, and update expression.

1// Basic structure of the for loop
2for (initialization; condition; update) {
3  // Code block to execute
4}

In practice in Jurassic Park, we can use the

for
loop to automate routine tasks:

1// Checking the health of every dinosaur in a sector
2let dinosaurs = ["Tyrannosaurus", "Velociraptor", "Triceratops", "Stegosaurus", "Brachiosaurus"];
3
4for (let i = 0; i < dinosaurs.length; i++) {
5  console.log(`Checking health status: ${dinosaurs[i]}`);
6  // Code to check the health of a specific dinosaur...
7}
8
9// Result:
10// Checking health status: Tyrannosaurus
11// Checking health status: Velociraptor
12// Checking health status: Triceratops
13// Checking health status: Stegosaurus
14// Checking health status: Brachiosaurus
15
16// Security camera monitoring
17for (let camera = 1; camera <= 10; camera++) {
18  console.log(`Checking camera #${camera}`);
19  // Code to analyze the camera feed...
20}
21
22// Generating a daily report for the last 7 days
23for (let day = 1; day <= 7; day++) {
24  console.log(`Generating report for day #${day}`);
25  // Code to generate the report for a specific day...
26}

The

for
loop has three main elements:

  1. Initialization (e.g.,
    let i = 0
    ) - executed once, before the loop starts
  2. Condition (e.g.,
    i < dinosaurs.length
    ) - checked before each iteration; the loop ends when the condition returns
    false
  3. Update (e.g.,
    i++
    ) - executed after each iteration

The for...of Loop

The

for...of
loop is a newer and more elegant form of loop that allows iterating over elements of a collection (arrays, strings, maps, sets, etc.) without the need to track indices.

1// Structure of the for...of loop
2for (let element of collection) {
3  // Code block to execute for each element
4}

The

for...of
loop is particularly useful when we're interested in the elements themselves, not their indices:

1// Checking the health of each dinosaur using for...of
2let dinosaurs = ["Tyrannosaurus", "Velociraptor", "Triceratops", "Stegosaurus", "Brachiosaurus"];
3
4for (let dinosaur of dinosaurs) {
5  console.log(`Checking health status: ${dinosaur}`);
6  // Code to check the health of a specific dinosaur...
7}
8
9// Checking food supply levels for different food types
10let foodSupplies = {
11  meat: 500, // kg
12  leaves: 1200, // kg
13  fruit: 300, // kg
14  fish: 200 // kg
15};
16
17// Note: for...of doesn't work directly on objects, but we can use Object.entries()
18for (let [foodType, amount] of Object.entries(foodSupplies)) {
19  console.log(`Food: ${foodType}, Amount: ${amount} kg`);
20
21  if (amount < 300) {
22    console.log(`WARNING: Low supply of ${foodType}! Needs restocking.`);
23  }
24}
25
26// Result:
27// Food: meat, Amount: 500 kg
28// Food: leaves, Amount: 1200 kg
29// Food: fruit, Amount: 300 kg
30// Food: fish, Amount: 200 kg
31// WARNING: Low supply of fish! Needs restocking.

The for...in Loop

The

for...in
loop is designed for iterating over the properties of an object. It returns the names of keys (properties) of the object.

1// Structure of the for...in loop
2for (let key in object) {
3  // Code block to execute for each key
4}

Example use in Jurassic Park:

1// Analyzing dinosaur data
2let tyrannosaurus = {
3  species: "Tyrannosaurus Rex",
4  age: 12,
5  weight: 8000, // kg
6  length: 12, // m
7  height: 5.6, // m
8  speed: 27, // km/h
9  aggressionLevel: "Very high"
10};
11
12// Displaying all information about the dinosaur
13for (let trait in tyrannosaurus) {
14  console.log(`${trait}: ${tyrannosaurus[trait]}`);
15}
16
17// Checking which dinosaur traits exceed safety values
18let safetyLimits = {
19  weight: 5000, // kg
20  speed: 25, // km/h
21  aggressionLevel: "High"
22};
23
24for (let parameter in safetyLimits) {
25  if (tyrannosaurus[parameter] > safetyLimits[parameter] ||
26      (parameter === "aggressionLevel" && tyrannosaurus[parameter] === "Very high")) {
27    console.log(`WARNING: Parameter ${parameter} exceeds safety values!`);
28  }
29}
30
31// Result:
32// WARNING: Parameter weight exceeds safety values!
33// WARNING: Parameter speed exceeds safety values!
34// WARNING: Parameter aggressionLevel exceeds safety values!

Important note: The

for...in
loop iterates over all properties of an object, including inherited ones. If we want to limit ourselves to only the object's own properties, we can use the
hasOwnProperty()
method:

1for (let trait in tyrannosaurus) {
2  if (tyrannosaurus.hasOwnProperty(trait)) {
3    console.log(`${trait}: ${tyrannosaurus[trait]}`);
4  }
5}

Differences Between for...of and for...in

It's important to understand the difference between these two types of loops:

  • for...of - iterates over values of collection elements (arrays, strings, etc.)
  • for...in - iterates over property names (keys) of an object
1let dinosaurNames = ["T-Rex", "Raptor", "Triceratops"];
2
3// for...of (values)
4for (let name of dinosaurNames) {
5  console.log(name); // "T-Rex", "Raptor", "Triceratops"
6}
7
8// for...in (indices/keys)
9for (let index in dinosaurNames) {
10  console.log(index); // "0", "1", "2"
11  console.log(dinosaurNames[index]); // "T-Rex", "Raptor", "Triceratops"
12}

The while Loop

The

while
loop executes a block of code as long as a specified condition is true. Unlike the
for
loop, the
while
loop only has a condition.

1// Structure of the while loop
2while (condition) {
3  // Code block to execute
4}

In Jurassic Park, the

while
loop can be used for processes that don't have a predetermined number of iterations:

1// Egg incubator temperature monitoring system
2let temperature = 37.5; // degrees Celsius
3let targetTemperature = 38.2;
4let temperatureIncrement = 0.1;
5
6console.log("Starting incubator heating process...");
7
8while (temperature < targetTemperature) {
9  console.log(`Current temperature: ${temperature.toFixed(1)}°C`);
10  temperature += temperatureIncrement;
11  // Code to simulate time passing...
12}
13
14console.log(`Target temperature reached: ${temperature.toFixed(1)}°C`);
15
16// Power level monitoring system
17let powerLevel = 100; // percent
18let criticalLevel = 20;
19let powerDrop = 5;
20
21console.log("Monitoring power level after main generator failure...");
22
23while (powerLevel > criticalLevel) {
24  console.log(`Power level: ${powerLevel}%`);
25  powerLevel -= powerDrop;
26  // Code to simulate time passing...
27}
28
29console.log(`ALARM! Critical power level: ${powerLevel}%`);
30console.log("Launching emergency protocol...");

The do...while Loop

The

do...while
loop is similar to the
while
loop, but with one key difference: the code block is always executed at least once before the condition is checked.

1// Structure of the do...while loop
2do {
3  // Code block to execute
4} while (condition);

This loop is useful when we want the code to execute at least once, regardless of the condition:

1// Security system startup procedure
2let systemOperational = false;
3let attemptCount = 0;
4let maxAttempts = 3;
5
6do {
7  console.log("Attempting to start the security system...");
8  attemptCount++;
9
10  // Simulating random system behavior
11  systemOperational = Math.random() > 0.5; // 50% chance of success
12
13  if (systemOperational) {
14    console.log("Security system started successfully!");
15  } else {
16    console.log(`System startup failed. Attempt ${attemptCount} of ${maxAttempts}.`);
17  }
18
19} while (!systemOperational && attemptCount < maxAttempts);
20
21if (!systemOperational) {
22  console.log("CRITICAL ERROR: Security system cannot be started. Technical intervention required!");
23}
24
25// Evacuation procedure
26let remainingPeople = 100;
27
28do {
29  console.log(`${remainingPeople} people remaining for evacuation.`);
30  // Simulation - each iteration represents one evacuated group
31  let groupSize = Math.floor(Math.random() * 20) + 10; // 10-29 people
32  remainingPeople -= groupSize;
33
34  // Making sure we don't get a negative number
35  if (remainingPeople < 0) remainingPeople = 0;
36
37  console.log(`Evacuated a group of ${groupSize} people.`);
38
39} while (remainingPeople > 0);
40
41console.log("Everyone has been evacuated. The facility is empty.");

Breaking and Continuing Loops: break and continue

JavaScript offers two special statements for controlling loop flow:

  • break - immediately stops the loop and exits it
  • continue - stops the current iteration and moves to the next one

Example of Using break

1// Searching for a damaged fence section
2let fenceSections = [
3  { id: 1, status: "intact" },
4  { id: 2, status: "intact" },
5  { id: 3, status: "damaged" },
6  { id: 4, status: "intact" },
7  { id: 5, status: "intact" }
8];
9
10let damageFound = false;
11
12for (let i = 0; i < fenceSections.length; i++) {
13  console.log(`Checking section #${fenceSections[i].id}...`);
14
15  if (fenceSections[i].status === "damaged") {
16    console.log(`WARNING! Found damaged section #${fenceSections[i].id}!`);
17    console.log("Sending repair team...");
18    damageFound = true;
19    break; // Stop the loop when we find damage
20  }
21}
22
23if (!damageFound) {
24  console.log("All fence sections are intact.");
25}
26
27// Result:
28// Checking section #1...
29// Checking section #2...
30// Checking section #3...
31// WARNING! Found damaged section #3!
32// Sending repair team...

Example of Using continue

1// Checking dinosaur health, skipping those currently under examination
2let dinosaurs = [
3  { name: "Rex", species: "Tyrannosaurus", available: true },
4  { name: "Blue", species: "Velociraptor", available: false }, // Under examination
5  { name: "Spike", species: "Stegosaurus", available: true },
6  { name: "Cera", species: "Triceratops", available: false }, // Under examination
7  { name: "Bronty", species: "Brontosaurus", available: true }
8];
9
10console.log("Starting daily health checks...");
11
12for (let i = 0; i < dinosaurs.length; i++) {
13  if (!dinosaurs[i].available) {
14    console.log(`Dinosaur ${dinosaurs[i].name} (${dinosaurs[i].species}) is already under examination. Skipping.`);
15    continue; // Move to the next iteration, skipping the rest of the code in this iteration
16  }
17
18  console.log(`Conducting examination of dinosaur ${dinosaurs[i].name} (${dinosaurs[i].species})...`);
19  console.log("Examination complete. Health status: good.");
20}
21
22// Result:
23// Starting daily health checks...
24// Conducting examination of dinosaur Rex (Tyrannosaurus)...
25// Examination complete. Health status: good.
26// Dinosaur Blue (Velociraptor) is already under examination. Skipping.
27// Conducting examination of dinosaur Spike (Stegosaurus)...
28// Examination complete. Health status: good.
29// Dinosaur Cera (Triceratops) is already under examination. Skipping.
30// Conducting examination of dinosaur Bronty (Brontosaurus)...
31// Examination complete. Health status: good.

Nested Loops

Loops can also be nested inside each other, which is useful when working with multi-dimensional data:

1// Checking fence status in all sectors of Jurassic Park
2
3// Two-dimensional array: [sector][fence_section]
4let fenceStatus = [
5  // Sector 1
6  [
7    { id: "1A", condition: "intact" },
8    { id: "1B", condition: "intact" },
9    { id: "1C", condition: "damaged" }
10  ],
11  // Sector 2
12  [
13    { id: "2A", condition: "intact" },
14    { id: "2B", condition: "intact" },
15    { id: "2C", condition: "intact" }
16  ],
17  // Sector 3
18  [
19    { id: "3A", condition: "intact" },
20    { id: "3B", condition: "damaged" },
21    { id: "3C", condition: "intact" }
22  ]
23];
24
25console.log("Starting fence inspection in all sectors...");
26
27for (let i = 0; i < fenceStatus.length; i++) {
28  console.log(`
29Inspecting sector ${i + 1}:`);
30
31  let allIntact = true;
32
33  for (let j = 0; j < fenceStatus[i].length; j++) {
34    let section = fenceStatus[i][j];
35    console.log(`  Section ${section.id}: ${section.condition}`);
36
37    if (section.condition === "damaged") {
38      allIntact = false;
39      console.log(`  WARNING: Section ${section.id} requires repair!`);
40    }
41  }
42
43  if (allIntact) {
44    console.log(`  All fences in sector ${i + 1} are intact.`);
45  } else {
46    console.log(`  Damaged fences detected in sector ${i + 1}.`);
47  }
48}
49
50// Result:
51// Starting fence inspection in all sectors...
52//
53// Inspecting sector 1:
54//   Section 1A: intact
55//   Section 1B: intact
56//   Section 1C: damaged
57//   WARNING: Section 1C requires repair!
58//   Damaged fences detected in sector 1.
59//
60// Inspecting sector 2:
61//   Section 2A: intact
62//   Section 2B: intact
63//   Section 2C: intact
64//   All fences in sector 2 are intact.
65//
66// Inspecting sector 3:
67//   Section 3A: intact
68//   Section 3B: damaged
69//   WARNING: Section 3B requires repair!
70//   Section 3C: intact
71//   Damaged fences detected in sector 3.

Infinite Loops and How to Avoid Them

An infinite loop is a loop that never ends because its termination condition is never met. In Jurassic Park, an infinite loop in the security system could lead to catastrophe, similarly to how in programming it can cause application freezes or consume all resources.

Here's an example of an infinite loop:

1// WARNING: This is an infinite loop! Do not run this code!
2while (true) {
3  console.log("This will display forever!");
4}
5
6// Another example of an infinite loop:
7for (let i = 0; i >= 0; i++) {
8  console.log(i); // This will count forever!
9}

To avoid infinite loops:

  1. Make sure the loop termination condition is reachable
  2. Always update the variables used in the loop condition
  3. Consider adding an additional exit condition (e.g., iteration counter)
  4. Use the
    break
    statement as a safety measure
1// Safer version with iteration limit
2let maxIterations = 1000;
3let iterationCounter = 0;
4
5// Example of safe monitoring
6while (monitorPark()) {
7  // Park monitoring code...
8
9  iterationCounter++;
10  if (iterationCounter >= maxIterations) {
11    console.log("Maximum number of iterations reached. Breaking loop.");
12    break;
13  }
14}
15
16function monitorPark() {
17  // Monitoring logic...
18  return true; // Normally would return true or false depending on conditions
19}

Loop Practices and Patterns

1. Choosing the Right Loop

  • for - when you know the exact number of iterations or work with indices
  • for...of - when you want to iterate over collection elements (arrays, strings)
  • for...in - when you want to iterate over object properties
  • while - when the termination condition depends on external factors
  • do...while - when you want the code to execute at least once

2. Optimizing Loops

1// Non-optimal loop - array length is recalculated on each iteration
2for (let i = 0; i < dinosaurs.length; i++) {
3  // Code...
4}
5
6// Optimized loop - array length is calculated only once
7for (let i = 0, len = dinosaurs.length; i < len; i++) {
8  // Code...
9}

3. Early Loop Exit

1// Early loop exit after finding the first matching element
2function findDinosaur(name) {
3  for (let dinosaur of dinosaurDatabase) {
4    if (dinosaur.name === name) {
5      return dinosaur; // Immediate return upon finding
6    }
7  }
8  return null; // No matching dinosaur
9}

4. Avoiding Loop Counter Modification Inside the Loop

1// Dangerous - modifying the counter inside the loop
2for (let i = 0; i < 10; i++) {
3  console.log(i);
4  if (i === 5) {
5    i = 8; // Skipping some iterations - this can be confusing
6  }
7}
8
9// Better approach - use continue or break statements
10for (let i = 0; i < 10; i++) {
11  if (i > 5 && i < 9) {
12    continue; // Skip iterations 6, 7, 8
13  }
14  console.log(i);
15}

Summary

Loops in JavaScript, much like routine procedures in Jurassic Park, allow for the efficient execution of repetitive operations:

  1. for - for iterating through a specific number of repetitions
  2. for...of - for iterating over collection elements
  3. for...in - for iterating over object properties
  4. while - for executing code as long as a condition is true
  5. do...while - for executing code at least once, then as long as a condition is true

Additionally, control statements:

  • break - stops the entire loop
  • continue - moves to the next iteration

Choosing the right loop depends on the specific use case, but generally you should aim for:

  • Using the simplest loop appropriate for the task
  • Optimizing loops, especially for large data collections
  • Avoiding infinite loops
  • Using readable variable names and clear code structure

In the next lesson, we will look at functions, which allow organizing code into reusable blocks - essential for maintaining order in such a complex system as Jurassic Park.

Go to CodeWorlds