MGU Computer Science Series — Web Development: HTML, CSS, and JavaScript
Part IV: JavaScript — Interaction and Logic
Conditionals · Loops · Arrays · Dynamic Content
Chapter 23 of 30
23
MGU Computer Science Series  ·  Web Development: HTML, CSS, and JavaScript  ·  Library Textbook Edition

Chapter 23:
Conditionals, Loops,
and Dynamic Content

How JavaScript uses decisions and repetition to turn a list of data into a full section of a real, living web page

■ Part IV of VII ■

■ 10 Sections  •  Chapter 23 of 30 ■

Builds on variables, functions, events, and DOM selection from Chapters 19–22

Chapter Introduction and Learning Objectives

Open the home page of almost any website and look closely. A grid of cards. A list of articles. A row of event announcements. Each item shares the same shape — the same heading style, the same spacing, the same layout — yet each one shows different content. That page was almost certainly not built by hand-typing ten nearly identical blocks of HTML. It was built once, as a pattern, and then filled in automatically from a list of data.

This chapter teaches you the two tools that make that possible: conditionals, which let JavaScript make decisions, and loops, which let JavaScript repeat an action across every item in a collection. Together, these tools let a few lines of code generate entire sections of a page — card grids, resource lists, filtered galleries — from nothing more than an array of data. This is one of the most important turning points in the whole textbook: pages stop being something you type by hand and start being something your code builds.

Opening Question

A resource directory holds twenty links. A class roster holds thirty students, each with a grade that must be checked against a passing threshold. A photo gallery holds fifty images, but the page should only show the ones tagged "featured." None of these pages should be written by hand, one item at a time. What single pattern — decisions plus repetition — lets one small block of JavaScript handle all three? By the end of this chapter, you will be able to write that pattern yourself, and you will recognize it every time you encounter it on the web.

10Sections
11Objectives
19Key Terms
30Total Chapters

Learning Objectives

By the end of this chapter, you should be able to:

  1. 1Explain why dynamic web pages require logic in addition to static HTML.
  2. 2Write and evaluate comparison expressions using JavaScript's comparison operators.
  3. 3Combine conditions using the logical operators &&, ||, and !.
  4. 4Write and trace if, else if, and else statements.
  5. 5Create and access elements in arrays, including arrays of objects.
  6. 6Write for, for...of, and forEach loops to iterate over an array.
  7. 7Combine loops and conditionals to process and inspect collections of data.
  8. 8Use template strings to build multi-line HTML fragments with embedded data.
  9. 9Render a collection of data as HTML elements using a loop and innerHTML.
  10. 10Implement basic content filtering using a conditional or the array filter() method.
  11. 11Diagnose and fix common problems that occur in dynamically generated content.

Sections at a Glance

Sections 23.1 – 23.3
Making Decisions: Logic, Comparisons, and Conditionals
Boolean Logic · Comparison Operators · if / else

Why Dynamic Pages Need Logic

Before this chapter, your JavaScript handled one thing at a time: a single click, a single element, a single update. That kind of interaction is useful, but most real pages deal with collections — a list of articles, an array of resources, a set of categories. To work with collections, JavaScript needs two tools: conditionals, for making decisions, and loops, for repeating instructions across every item in a collection.

The page structure is defined once. The data fills it in. JavaScript uses logic to connect the two. This chapter builds both tools step by step. By the end, you will be able to take a list of data and produce a full section of HTML from it automatically — the same pattern that powers card grids, resource lists, announcement boards, and filtered galleries across the web.

Where This Is Heading

By Section 23.7 you will combine a loop with a template string to generate an entire row of cards from an array. By Section 23.9 you will let users filter that same data with the click of a button. Keep that destination in mind as you work through the smaller pieces in between.

Comparisons and Boolean Expressions

Every decision in JavaScript starts with a question that can be answered yes or no. JavaScript calls these answers Boolean values: true or false. A Boolean value is not a number or a string — it is a simple answer to a simple question, and it is the only kind of value a conditional statement can act on.

You create Boolean values with comparison operators. A comparison operator takes two values, compares them, and produces either true or false.

OperatorMeaningExampleResult
===Strictly equal5 === 5true
!==Strictly not equal5 !== 3true
>Greater than10 > 3true
<Less than3 < 10true
>=Greater than or equal5 >= 5true
<=Less than or equal4 <= 3false

Notice that equality uses three equals signs: ===. This is strict equality — it checks that two values share the same type and the same value. You may also encounter == (loose equality) in older code; it converts types before comparing, which can produce surprising results. Always use === in your own code.

Comparison Expressions
const temperature = 28;
const isHot = temperature > 25;
console.log(isHot);  // true

"hello" === "hello"   // true
"hello" === "Hello"   // false — uppercase H is different
7 !== 7                // false — they are equal, so "not equal" is false

Combining Comparisons with Logical Operators

Sometimes one comparison is not enough. You need to ask: is this AND that true? Or is this OR that true? JavaScript provides three logical operators.

OperatorMeaningExample
&&AND — both must be trueage > 12 && age < 18 is true only for ages 13–17
||OR — at least one must be trueday === "Sat" || day === "Sun" is true on weekends
!NOT — reverses the Boolean!isLoggedIn is true if NOT logged in
Logical Operators in Practice
const score = 72;
const passed = score >= 60 && score <= 100;
console.log(passed);  // true

const day = "Saturday";
const isWeekend = day === "Saturday" || day === "Sunday";
console.log(isWeekend);  // true

const isLoggedIn = false;
const showLoginButton = !isLoggedIn;
console.log(showLoginButton);  // true

Logical operators are especially useful when you need to check several conditions at once — for example, when deciding whether to show a particular card, highlight an item, or display an error message.

Code Reading 23-A
Tracing comparisons and logical operators
const score = 85;
const maxScore = 100;
const passing = 60;

const passed = score >= passing;
const perfect = score === maxScore;
const needsReview = score < passing || score > maxScore;

console.log(passed);
console.log(perfect);
console.log(needsReview);
  • Question 1What is the value of passed?
  • Question 2What is the value of perfect?
  • Question 3What is the value of needsReview?
  • Question 4Change score to 55. What would each variable become?

if and else

A conditional statement tells JavaScript to run one block of code when a condition is true and, optionally, a different block when it is false.

The Basic if Statement
const score = 88;

if (score >= 60) {
  console.log("Passing score.");
}

The condition must produce a Boolean value, either directly or through a comparison expression. An else block runs when the condition is false:

if / else
const score = 45;

if (score >= 60) {
  console.log("Passing score.");
} else {
  console.log("Score below passing. Please review the material.");
}

When you need to check several possible conditions in order, use else if. JavaScript checks each condition from top to bottom and stops at the first one that is true — only one block runs.

else if Chains
const score = 72;

if (score >= 90) {
  console.log("Excellent work.");
} else if (score >= 75) {
  console.log("Good work.");
} else if (score >= 60) {
  console.log("Passing.");
} else {
  console.log("Below passing.");
}
Trace
score is 72. Is 72 >= 90? No. Is 72 >= 75? No. Is 72 >= 60? Yes. Output: "Passing." The final else never runs because a match was already found.

In the browser, conditionals let you decide what content appears based on data or user input:

Controlling Page Content
const username = "Martina";
const greeting = document.querySelector("#greeting");

if (username !== "") {
  greeting.textContent = "Welcome back, " + username + "!";
} else {
  greeting.textContent = "Welcome! Please sign in.";
}

This is a common pattern. The HTML does not change — the JavaScript decides which message belongs in it.

Common Mistake

One of the most frequent JavaScript errors is using a single = (assignment) when you mean === (comparison). if (score = 10) does not compare anything — it sets score to 10 and then treats that value as the condition. Always write if (score === 10) when you intend to compare.

Code Tracing 23-B
Trace through an else-if chain
const hour = 14;
let greeting;

if (hour < 12) {
  greeting = "Good morning.";
} else if (hour < 17) {
  greeting = "Good afternoon.";
} else {
  greeting = "Good evening.";
}

console.log(greeting);
  • Question 1What is the output?
  • Question 2Change hour to 9. What is the output now?
  • Question 3Change hour to 19. What is the output?
Sections 23.4 – 23.6
Working with Collections: Arrays and Loops
Arrays · Objects · for, for...of, forEach

Arrays at an Introductory Level

Most of the work in this chapter involves collections of data — not a single value, but a group of related values. JavaScript stores ordered collections in a structure called an array. Each value in the list is called an element, and the elements are enclosed in square brackets and separated by commas.

Declaring Arrays
const colors = ["red", "green", "blue"];
const scores = [88, 95, 72, 61, 100];
const topics = ["HTML", "CSS", "JavaScript"];

Each element has a position in the array called its index. Array indexes start at 0, not 1. The first element is at index 0, the second at index 1, and so on.

Accessing Elements by Index
const fruits = ["apple", "banana", "cherry"];

console.log(fruits[0]);  // "apple"
console.log(fruits[1]);  // "banana"
console.log(fruits[2]);  // "cherry"
Watch the Off-by-One

Zero-based counting is a frequent source of beginner errors. The last element of a three-item array is at index 2, not 3. Asking for index 3 in this array produces undefined — nothing.

Every array has a length property that tells you how many elements it contains. This will matter when you write loops, because you often need to know how many times to repeat an action.

The length Property
const topics = ["HTML", "CSS", "JavaScript"];
console.log(topics.length);  // 3

Arrays of Objects

A single piece of data — just the string "HTML" — is useful, but most websites work with richer information: a title, a description, a category, a link. JavaScript handles this with objects. An object groups related pieces of information together under named labels called properties, accessed with dot notation.

A Single Object
const lesson = {
  title: "What Is HTML?",
  category: "HTML",
  duration: "15 min"
};

console.log(lesson.title);     // "What Is HTML?"
console.log(lesson.category);  // "HTML"

An array of objects is a list where every element is an object. This is how almost all real web data is organized:

An Array of Objects
const lessons = [
  { title: "What Is HTML?",     category: "HTML",       duration: "15 min" },
  { title: "Writing CSS",       category: "CSS",        duration: "20 min" },
  { title: "JavaScript Basics", category: "JavaScript", duration: "25 min" }
];

console.log(lessons[0].title);     // "What Is HTML?"
console.log(lessons[2].duration);  // "25 min"
Reading Dot-and-Bracket Notation

Read lessons[0].title as: "Go to the first item in the lessons array. Then look at its title property." Arrays of objects are the kind of data you will iterate through for the rest of this chapter, so make sure this reading feels natural before moving on.

Predict the Result 23-C
Reading an array of objects without running the code
const resources = [
  { name: "HTML Reference",  type: "guide",  free: true  },
  { name: "CSS Selectors",   type: "guide",  free: true  },
  { name: "JS Fundamentals", type: "course", free: false }
];
  • Question 1What does resources.length return?
  • Question 2What does resources[1].name return?
  • Question 3What does resources[2].free return?
  • Question 4What does resources[3] return? Why?

Loops in JavaScript

A loop repeats a block of code multiple times without writing it out multiple times. Imagine a list of ten resources: without loops, you would need ten separate blocks of code to build ten separate cards. Change the list to twenty resources and you would need twenty blocks. With a loop, you write the pattern once and it repeats automatically for every item.

The for Loop

A Counting Loop
for (let i = 0; i < 5; i++) {
  console.log("Step " + i);
}
Output
Step 0
Step 1
Step 2
Step 3
Step 4

A for loop has three parts inside the parentheses, separated by semicolons: for (initialization; condition; update) { ... }

  • Initialization — let i = 0 — runs once, creating the counter and setting it to 0.
  • Condition — i < 5 — checked before every iteration. True runs the body; false stops the loop.
  • Update — i++ — shorthand for i = i + 1; runs after every iteration.
Using the Counter as an Array Index
const topics = ["HTML", "CSS", "JavaScript"];

for (let i = 0; i < topics.length; i++) {
  console.log(topics[i]);
}
Why topics.length and Not a Fixed Number

Using topics.length in the condition instead of a hard-coded number means the loop automatically adjusts if you later add or remove items from the array. This is good practice you should follow in your own loops.

The for...of Loop

A Simpler Form
const topics = ["HTML", "CSS", "JavaScript"];

for (const topic of topics) {
  console.log(topic);
}

for...of automatically moves through every element, placing each one into the temporary variable topic for that iteration. You do not need to manage a counter or worry about going past the end of the array.

The forEach Method

forEach
const topics = ["HTML", "CSS", "JavaScript"];

topics.forEach(function(topic) {
  console.log(topic);
});

forEach produces the same result as for...of. Use for...of when you just need each element. Use a for loop when you also need the index — for example, to number items or access a specific position. You will see all three forms in real projects.

Code Tracing 23-D
Tracing a for loop with an accumulator
const scores = [88, 74, 92, 61];
let total = 0;

for (let i = 0; i < scores.length; i++) {
  total = total + scores[i];
  console.log("After step " + i + ", total is " + total);
}

console.log("Final total: " + total);
  • Question 1Write the complete output.
  • Question 2What would happen if the condition were i <= scores.length instead of i < scores.length?

Iterating Through Data

Now combine what you know: use a loop to move through an array of objects, and use each object's properties during each iteration.

Looping Through an Array of Objects
const lessons = [
  { title: "What Is HTML?",     category: "HTML",       duration: "15 min" },
  { title: "Writing CSS",       category: "CSS",        duration: "20 min" },
  { title: "JavaScript Basics", category: "JavaScript", duration: "25 min" }
];

for (const lesson of lessons) {
  console.log(lesson.title + " — " + lesson.duration);
}

Loops and conditionals work together naturally. Inside the loop body, you can test a condition and only act on elements that match — a first glimpse of filtering, which Section 23.9 expands on.

Combining a Loop with a Condition
for (const lesson of lessons) {
  if (lesson.category === "HTML") {
    console.log(lesson.title);
  }
}
Worked Example 23-E
Logging a resource list with a ternary expression
  • GoalPrint a formatted line for each resource in an array, showing whether it is free or paid.
for (const resource of resources) {
  const accessLabel = resource.free ? "Free" : "Paid";
  console.log(resource.name + " (" + resource.type + ") — " + accessLabel);
}

What is resource.free ? "Free" : "Paid"? This is a ternary expression — a compact way of writing an if/else that produces a single value: condition ? valueIfTrue : valueIfFalse. Read it as: "If resource.free is true, use "Free". Otherwise use "Paid"." You will see this pattern constantly once you start embedding logic inside template strings.

Sections 23.7 – 23.10
From Data to Page: Building and Debugging Dynamic Content
Template Strings · Rendering · Filtering · Debugging

Building Repeated Content

Logging to the console is useful for learning and debugging, but the real goal in web development is building actual HTML on the page. The general pattern for building repeated HTML from data is: start with an empty string, loop through the data array, build one HTML fragment per item, append it to the growing result, and after the loop write the full result into the page with innerHTML.

HTML
<section id="lesson-list">
  <h2>Lessons</h2>
  <ul id="lessons-output"></ul>
</section>
JavaScript
const lessons = [
  { title: "What Is HTML?",     category: "HTML"       },
  { title: "Writing CSS",       category: "CSS"        },
  { title: "JavaScript Basics", category: "JavaScript" }
];

const listElement = document.querySelector("#lessons-output");
let listHTML = "";

for (const lesson of lessons) {
  listHTML += "<li>" + lesson.title + " (" + lesson.category + ")</li>";
}

listElement.innerHTML = listHTML;

Walk through the code carefully. let listHTML = "" starts with an empty string. Inside the loop, listHTML += appends a new <li> string after whatever is already there — the += operator means "add this to whatever is already in the variable." After the loop finishes, listElement.innerHTML = listHTML writes the complete string of HTML into the <ul> in a single step.

Building Cards Instead of List Items

A more realistic pattern uses cards, where each card draws on multiple properties from a data object:

JavaScript — Building a Card Grid
const resources = [
  { name: "MDN Web Docs",     type: "reference", free: true  },
  { name: "CSS-Tricks",       type: "guide",     free: true  },
  { name: "Frontend Masters", type: "course",    free: false }
];

const container = document.querySelector("#cards-output");
let cardsHTML = "";

for (const resource of resources) {
  const accessLabel = resource.free ? "Free" : "Paid";

  cardsHTML += `
    <div class="card">
      <h3>${resource.name}</h3>
      <p>${resource.type}</p>
      <span class="badge">${accessLabel}</span>
    </div>
  `;
}

container.innerHTML = cardsHTML;

After the loop runs, container.innerHTML receives the entire set of card HTML, and the browser renders all of the cards in the grid. The JavaScript inside the loop is a template — it repeats for every item in the array. Add more items to resources and you get more cards automatically, without touching any HTML or CSS.

innerHTML and User Input

When you write content into innerHTML, the browser interprets it as real HTML. If any of the data comes from user input — something typed into a field — inserting it directly into innerHTML can be unsafe. The data in this chapter's examples is written directly in the JavaScript file, so it is safe here. Chapter 24 covers safe handling of user input in detail.

Template Strings for HTML Fragments

Template strings make building HTML fragments significantly cleaner than concatenating pieces with +. A template string uses backticks instead of quotes, can span multiple lines, and embeds expressions using ${}.

Recall: Template Strings
const name = "Martina";
const score = 92;

const message = `Hello, ${name}. Your score is ${score}.`;
console.log(message);
// Hello, Martina. Your score is 92.

Compare building HTML with string concatenation versus a template string:

Hard to Read
cardsHTML += "<div class=\"card\"><h3>" + resource.name + "</h3><p>" + resource.type + "</p></div>";
Much Easier to Read
cardsHTML += `
  <div class="card">
    <h3>${resource.name}</h3>
    <p>${resource.type}</p>
  </div>
`;

The template string can span multiple lines without escape characters, and its indentation visually matches the HTML it produces. Any JavaScript expression — including a ternary — can go inside ${}:

Embedding Expressions
const item = { name: "JavaScript.info", free: true, rating: 4.8 };

const cardHTML = `
  <div class="card">
    <h3>${item.name}</h3>
    <p>Rating: ${item.rating}/5</p>
    <span class="badge">${item.free ? "Free" : "Paid"}</span>
  </div>
`;

The ternary inside ${} produces different text based on the data. This is how a single template can produce visually different cards for different kinds of items — for example, changing a class name as well as the text it displays.

Worked Example 23-F
Reading a template string with a conditional class
const announcements = [
  { title: "New Lessons Added", date: "2024-09-01", important: true  },
  { title: "Site Maintenance",  date: "2024-09-08", important: false },
  { title: "Registration Open", date: "2024-09-15", important: true  }
];

let html = "";

for (const item of announcements) {
  html += `
    <article class="announcement${item.important ? " announcement--important" : ""}">
      <h3>${item.title}</h3>
      <time datetime="${item.date}">${item.date}</time>
    </article>
  `;
}

document.querySelector("#announcements").innerHTML = html;
  • Question 1How many <article> elements will be inserted into the page?
  • Question 2For the first announcement, what will the complete class attribute be?
  • Question 3For the second announcement, what will the complete class attribute be?
The Pattern That Powers Real Websites

The HTML file behind a data-driven section often contains no hand-written cards at all — only an empty container. The JavaScript builds every card from an array: loop through the data, build one template per item, append it to a growing string, and write the result into the container with innerHTML. To add new content, you add one more object to the array. The page updates with no changes to HTML or CSS.

Filtering Content at an Introductory Level

A common web page feature is a filter: a set of buttons or controls that lets users show only certain items. At this stage, you can build a simple version with JavaScript: read the data array, apply a condition, and build HTML from only the items that match.

Filtering with if Inside a Loop
for (const resource of resources) {
  if (resource.free === true) {
    output += `
      <div class="card">
        <h3>${resource.name}</h3>
        <p>${resource.type}</p>
      </div>
    `;
  }
}

container.innerHTML = output;

This builds cards only for resources where resource.free === true. To let users control the filter, connect buttons to a function that rebuilds the list:

Filter Buttons and a Render Function
function buildCards(filter) {
  const container = document.querySelector("#resource-list");
  let output = "";

  for (const resource of resources) {
    const shouldShow =
      filter === "all" ||
      (filter === "free" && resource.free === true) ||
      (filter === "paid" && resource.free === false);

    if (shouldShow) {
      output += `
        <div class="card">
          <h3>${resource.name}</h3>
          <p>${resource.free ? "Free" : "Paid"}</p>
        </div>
      `;
    }
  }

  container.innerHTML = output;
}

buildCards("all");

document.querySelector("#btn-free").addEventListener("click", function () {
  buildCards("free");
});

The function takes a filter string. Inside the loop, shouldShow becomes true or false based on the filter and the current resource. When a user clicks a filter button, the event listener calls buildCards with a different filter string, the function re-runs, and container.innerHTML is replaced with new content.

A Pattern Worth Remembering

One function that renders the page from data, called again whenever something changes, is one of the most important patterns in front-end web development. More advanced frameworks like React build on exactly this idea — you can already see its shape clearly in plain JavaScript.

The array.filter() Method

JavaScript arrays have a built-in filter method that returns a new array containing only the elements that pass a test, without modifying the original array.

filter()
const freeResources = resources.filter(function(resource) {
  return resource.free === true;
});

console.log(freeResources.length);  // 3

The function you pass to filter runs once per element and should return true to keep the element or false to exclude it. The if-inside-a-loop approach is simpler while you are learning; the filter-then-loop approach is cleaner once you are comfortable. You will see both in real codebases.

Debugging Dynamic Content

Dynamic content introduces a new category of problems. The HTML you see in the browser is not in your .html file — it exists only after JavaScript runs. This can make problems harder to spot at first.

SymptomWhat to Check
Nothing appears on the pageLog the container with console.log(container) — null means the selector is wrong. Check resources.length for an empty array. Log inside the loop to confirm it runs. Check output.length before assigning innerHTML.
Some items missingA conditional is blocking items. Check for = instead of ===, and check for comparing a Boolean to a string, such as resource.free === "true".
HTML looks malformedCheck the template string for unclosed tags, missing quotes on attributes, or mismatched backticks. Inspect the actual generated HTML in the Elements panel.
Cards appear but look wrongUsually a CSS problem, not JavaScript. Confirm class names in the template string exactly match class names in the stylesheet.
Useful Debugging Logs
// Is the selector finding the right element?
console.log(container);

// Is the data array populated?
console.log(resources.length);

// Is the loop actually running?
for (const resource of resources) {
  console.log("Processing:", resource.name);
}

// What type is this value, really?
console.log(resource.name, "— free:", resource.free, "— type:", typeof resource.free);

typeof returns a value's data type as a string. If typeof resource.free returns "string" when you expected "boolean", you have found the bug in your data rather than your logic.

Debugging Checklist for Dynamic Content

Before chasing the data or the logic, confirm the basics: the JavaScript file is linked correctly; the HTML id matches the selector; the array is populated and accessible at the point the loop runs; the loop is confirmed to iterate with a console log; the output string is non-empty before innerHTML is set; class names in the template string match the CSS; and the browser console shows no errors.

Chapter Summary

Key Terms

array
An ordered collection of values stored in a single variable. Each value is an element with a numeric index beginning at zero.
Boolean
A value that is either true or false. The result of any comparison expression.
comparison operator
A symbol that compares two values and produces a Boolean: ===, !==, >, <, >=, <=.
conditional statement
A structure (if, else if, else) that runs code only when a specified condition is true.
dynamic content
Page content generated by JavaScript from data, rather than written directly in the HTML file.
element (array)
A single value stored inside an array, accessed by its index.
filter() method
A built-in array method that returns a new array containing only the elements that pass a test function.
for loop
A loop structure that repeats code a controlled number of times using an index counter.
for...of loop
A loop structure that iterates through every element of an array, assigning each to a temporary variable.
forEach method
A built-in array method that calls a function once for each element.
index
The numeric position of an element in an array. Array indexes begin at zero.
innerHTML
A DOM property that reads or writes the HTML content inside an element as a string.
logical operator
An operator that combines Boolean values: && (AND), || (OR), ! (NOT).
loop
A structure that repeats a block of code multiple times, typically over every element in an array.
object
A value that groups multiple properties together under named labels, accessed with dot notation.
property
A named piece of data inside an object. Accessed as object.propertyName.
strict equality (===)
A comparison that returns true only when both values share the same type and the same value.
template string
A string delimited by backticks that can span multiple lines and embed expressions using ${}.
ternary expression
A compact if/else expression written as condition ? valueIfTrue : valueIfFalse.

Concept Check

Answer these questions before beginning the full review questions. They check basic understanding, not deep analysis.

  1. What is the difference between a comparison operator and a logical operator? Give one example of each.
  2. Why does JavaScript count array indexes starting at 0 instead of 1?
  3. What is the difference between a for loop and a for...of loop?
  4. What is an array of objects, and why is it useful for representing real web data?
  5. What does the += operator do when building an HTML string inside a loop?
  6. What is a template string, and what symbol is used instead of quotation marks?
  7. What is the difference between using an if statement inside a loop to filter data and using the array's filter() method?

Common Misconceptions

Misconception 1
"Using a single equals sign inside an if statement compares two values."
A single = is the assignment operator — it sets a variable to a value and does not compare anything. if (score = 10) assigns 10 to score and then evaluates that assigned value as the condition, which can silently produce incorrect behavior. Comparison requires ===.
Misconception 2
"Array indexes start at 1, the way everyday counting does."
JavaScript array indexes are zero-based. The first element is at index 0, and the last element of an array with length equal to n is at index n − 1. Asking for index n returns undefined rather than an error, which can hide the mistake.
Misconception 3
"Setting innerHTML inside the loop, once per item, works the same as building a string and setting it once after the loop."
Setting container.innerHTML inside the loop replaces the entire contents of the container on every iteration. Each new assignment erases the previous one, so only the last item ends up on the page. Build the full HTML string first, then assign it to innerHTML a single time after the loop finishes.
Misconception 4
"The array filter() method changes the original array."
filter() always returns a brand-new array containing only the elements that passed the test function. The original array is left completely unchanged. If you need the filtered result later, you must store it in a new variable.
Misconception 5
"Loose equality (==) and strict equality (===) always behave the same way."
Loose equality converts the types of its operands before comparing, which can make unrelated-looking values appear equal. Strict equality requires both the type and the value to match, with no conversion. This textbook uses === exclusively to avoid the surprising behavior of ==.
ActivitiesLogic and Data in Real Websites

These activities connect chapter concepts to real websites. No advanced tools required — only careful observation and a code editor.

  1. Spot the Pattern. Find a section on a website you use often that is built from repeated items — a card grid, a list, a gallery. Open Developer Tools and inspect two of the items. Are they structurally identical except for their text and images? Write two sentences describing what you found.
  2. Array From Scratch. Pick a real collection you care about — favorite songs, books, or recipes — and write it as an array of at least five objects, each with three or more properties. Save it as a JavaScript file and confirm it is valid by logging length and one property from the first and last elements.
  3. Filter Design. Sketch, on paper or in words, a filter bar for a real website you use. Describe what condition each filter button would check against the underlying data.
  4. Decision Trail. Write out, in plain English, the chain of if/else if/else decisions a streaming service might use to decide whether to show a "Continue Watching" badge on a video card.
Mini-ProjectFilterable Resource List

Build a one-page application called Resource Directory. The page displays a collection of learning resources as cards in a CSS Grid, and users filter them with category buttons. This project brings together semantic HTML, CSS Grid and variables, external JavaScript, DOM selection, event listeners, template strings, loops, conditionals, and content filtering.

Project Brief
resource-directory/
  • DataAn array of at least eight resource objects, each with name, type ("reference", "guide", or "course"), description, free, and url.
  • RenderA renderResources(items) function that builds one card per item with a template string and writes the result into #resource-grid with innerHTML, plus an updated count display.
  • FilterAn applyFilter(filter) function that uses resources.filter() to narrow the data by type, then calls renderResources.
  • WiringFilter buttons, each with a data-filter attribute, wired up with addEventListener("click", ...) to mark themselves active and call applyFilter.
  • Empty stateA message shown when a filter matches zero resources, instead of an empty grid.
Core Render Function
function renderResources(items) {
  const grid = document.querySelector("#resource-grid");
  const countDisplay = document.querySelector("#count-display");

  countDisplay.textContent = `Showing ${items.length} resource${items.length !== 1 ? "s" : ""}`;

  if (items.length === 0) {
    grid.innerHTML = `<p class="empty-message">No resources found for this filter.</p>`;
    return;
  }

  let html = "";
  for (const resource of items) {
    html += `
      <div class="card">
        <h3>${resource.name}</h3>
        <span class="badge badge--${resource.type}">${resource.type}</span>
        <p>${resource.description}</p>
        <a href="${resource.url}" target="_blank" rel="noopener noreferrer">Visit ${resource.name}</a>
      </div>
    `;
  }
  grid.innerHTML = html;
}
Mini-Project Completion Checklist
  • The data array contains at least eight resources, each with all five required properties.
  • renderResources builds cards using a template string inside a loop, and updates the count display.
  • applyFilter filters the data with filter() and calls renderResources.
  • Filter buttons update which button is marked active and re-render the grid.
  • An empty-state message appears when no items match the current filter.
  • All resource links use target="_blank" and rel="noopener noreferrer".
  • The page shows no errors in the browser console.

Accessibility Check

Dynamic content introduces accessibility concerns that static pages do not have. Review any project you build against these points: filter controls should be real <button> elements, not styled <div>s, so they remain keyboard accessible by default. The active filter should be visually distinguishable, and can also be marked with aria-pressed="true" for assistive technologies. Card links should use meaningful text — "Visit MDN Web Docs" rather than a bare "Click here." A count display that updates with each filter change can be marked role="status" with aria-live="polite" so screen readers announce the new total automatically. Finally, tab through the finished page without a mouse — every filter button and every card link must be reachable and operable from the keyboard alone.

ReviewReview Questions

Recall and Vocabulary

  1. What is a Boolean value? Name the six comparison operators covered in this chapter.
  2. What is the difference between = and ===? Why does using = inside an if statement cause a bug?
  3. What is an array? What is an element? What number does array indexing start from?
  4. What is the difference between an array and an object? How do you access a property of an object?
  5. What are the three parts of a for loop's parentheses? Explain what each one does.
  6. What is the difference between a for...of loop and a forEach method call?
  7. What does the += operator do when used with strings?
  8. What does innerHTML do, and what kind of value must be assigned to it?

Understanding and Explanation

  1. Explain in your own words why a website would use a loop to build a card grid instead of writing each card by hand in HTML.
  2. The chapter says, "the loop body is a template, and the loop repeats that template for every item." Explain what this means using an example that does not appear in the chapter.
  3. Explain the difference between filtering with an if statement inside a for loop and filtering with the array's filter() method. Which one creates a new array?
  4. Why is i < array.length generally safer to use in a for loop's condition than a fixed number like i < 10?
  5. Explain why building an HTML string and setting innerHTML once after a loop finishes is better than setting innerHTML inside the loop on every iteration.
  6. Why does comparing resource.free === true behave differently from comparing resource.free === "true"? What problem could this difference cause?

Application and Analysis

  1. A class roster array contains objects with name and grade properties. Write a loop that builds a list showing only students with a grade of 70 or higher, with each list item formatted as "Name: Grade".
  2. A filter system has three buttons: "All," "Pinned," and "Unpinned." Write the condition you would use inside a render function to decide whether each announcement object should appear for each of the three filter values.
  3. A developer writes class="card ${resource.featured ? 'card--featured' : ''}" inside a template string. Explain what this produces when resource.featured is true and when it is false.
  4. A page shows zero cards after a loop runs, even though the data array has five items in it. List three things you would check, in order, to find the bug.

Design and Synthesis

  1. Design a small array of at least four objects representing data of your choice — favorite movies, local restaurants, or a study playlist. Write the JavaScript loop and template string that would render this data as cards in a container with id="output".
  2. Extend the array and loop from Question 19 by adding one filter button that shows only items matching a condition of your choice. Describe the function you would write to handle the button's click event.

Mixed Review

These questions revisit earlier chapters alongside the new material in Chapter 23.

  1. A card component built dynamically from an array uses <article> as its outer element. Explain why <article> is a good semantic choice here rather than <div>.
  2. You want dynamically inserted cards to appear inside a CSS Grid layout. Should the grid styles be defined on the container in your stylesheet, or generated by JavaScript along with the cards? Explain your reasoning.
  3. Generated card HTML includes <a href="${resource.url}" target="_blank" rel="noopener noreferrer">. What does rel="noopener noreferrer" do, and why does it matter when opening links in a new tab?
  4. A classmate says, "Instead of building a string and setting innerHTML once at the end, I'll set innerHTML inside the loop, once per card." What is the problem with this approach?
Chapter 23 Checklist
Use this to confirm your understanding before moving to Chapter 24
Concepts
  • I can write comparison expressions and combine them with logical operators.
  • I can write and trace if, else if, and else statements.
  • I can explain the difference between an array, an element, an index, and a property.
  • I can write for, for...of, and forEach loops over an array.
  • I can explain why array indexing starts at zero.
Building Dynamic Pages
  • I can build an HTML fragment for one data item using a template string.
  • I can loop through an array of objects and accumulate HTML into a single string.
  • I can write the result of a loop into the page with innerHTML, only once, after the loop completes.
  • I can filter a data array using an if statement inside a loop or the filter() method.
  • I can connect filter buttons to a render function with event listeners.
Debugging
  • I know how to check whether a selector found the right element.
  • I know how to confirm a loop is actually running.
  • I can distinguish a logic bug (wrong condition) from a styling bug (wrong class name).
Preview — Chapter 24
Forms, Validation, and User Feedback

Chapter 23 gave you the tools to turn data into page content. Chapter 24 turns to one of the most common interfaces on the web: forms. You will learn how to read values from form fields with JavaScript, define validation rules, display error and success messages near the relevant fields, and prevent a form from submitting when its data is not yet valid. You will also learn about accessible form feedback — writing messages that assistive technologies can announce, so every user receives the guidance they need. The conditionals and loops from this chapter will return constantly: checking required fields is a conditional, and validating a whole form often means looping through its fields one at a time.

MGU Library Connection
  • Appendix G: JavaScript Browser Reference
  • Appendix H: Forms and User Feedback Reference
  • Appendix M: Full Glossary of Web Development Terms
  • Companion resource: JavaScript DOM Guide
  • Companion resource: Event Listener Guide
  • Companion resource: Web Debugging Checklist
  • Next chapter: Chapter 24, Forms, Validation, and User Feedback (builds directly on this chapter's loops and conditionals)