0 / 91
Week 3 · Day 19 of 91

Arrays and iteration

JavaScript Foundations I

Objective

Store collections and process each item deliberately.

Variables are measured signals, functions are reusable circuit blocks, and control flow determines which path becomes active.

  • array creation and indexing
  • for loops and for...of
  • basic array methods

Why this matters

Every variable so far has held exactly one value. Real work is never one value: an inventory has fifty components, an order has twelve lines, a log has a thousand entries. Today you learn the structure that holds many values in order — the array — and the two ways to visit every item in one.

This unlocks a kind of program you could not write yesterday: one whose amount of work depends on its data rather than on how many lines you typed. Five components or five hundred, the code is the same length.

Creating and indexing an array

An array is an ordered list of values. You write one with square brackets, values separated by commas.

const names = ["Resistor 220", "Resistor 330", "Capacitor 100n", "LED red", "Diode 1N4148"];
const stock = [42, 8, 120, 3, 60];

Each value sits at a numbered position called an index, and indexes start at zero. Read one with square brackets after the array name:

console.log(names[0]);
console.log(names.length);
console.log(names[names.length - 1]);
console.log(names[5]);
Resistor 220
5
Diode 1N4148
undefined

Four facts in one block. names[0] is the first item. .length is how many items there are — a property, so no parentheses. Because counting starts at zero, the last index is always length - 1: 5 items, last one at index 4. And reading past the end is not an error — JavaScript hands back undefined, the "nothing was ever here" value from Day 15.

Off-by-one is the classic array bug

names[names.length] is always undefined, because the highest valid index is one less than the length. If a loop's last item comes out undefined, this is almost always why.

const on an array stops you replacing the whole array, but the contents can still change. .push(value) adds one item to the end:

const lowStock = [];
lowStock.push("LED red");
console.log(lowStock, lowStock.length);
[ 'LED red' ] 1

Starting from an empty array and pushing as you go is the pattern for "collect the items that match a rule".

An array is a numbered terminal strip

An array is a terminal block with positions printed on it. The strip has a fixed identity, and position 0 is a specific screw terminal — what is wired to it can change. You address a conductor by position rather than hunting through the loom, which is what stock[3] does.

The for loop

A loop repeats a block of code. The classic for loop repeats it once per index.

let total = 0;
for (let i = 0; i < stock.length; i = i + 1) {
  total += stock[i];
}
console.log("Total units:", total);
Total units: 233

The parentheses hold three parts separated by semicolons:

  1. let i = 0 — the start, run once. i is the counter, conventionally named i.
  2. i < stock.length — the condition, checked before each pass. While true, the body runs; the moment it is false, the loop ends.
  3. i = i + 1 — the step, run after each pass.

So i takes the values 0, 1, 2, 3, 4, and at i of 5 the condition 5 < 5 is false and the loop stops. i is declared with let because it must change.

total += stock[i] is shorthand for total = total + stock[i]. total is a variable outside the loop that accumulates a running result — an accumulator — which is why it is let and starts at 0.

i++ is an even shorter way to write i = i + 1, and you will see it everywhere.

Walking the shelf

The for loop is walking a shelf with a clipboard: start at bay 0, keep going while there are bays left, move one bay each time, and add each count to the running total. The clipboard total is the accumulator.

for...of

When you need each value and never the index, for...of says so more directly:

for (const name of names) {
  console.log("-", name);
}
- Resistor 220
- Resistor 330
- Capacitor 100n
- LED red
- Diode 1N4148

name is a fresh variable holding one item per pass; const is right because it is not reassigned within a pass. There is no counter to get wrong, so for...of is the safer default.

Use the classic for when you genuinely need i — and you need it whenever two arrays line up by position, as names and stock do. stock[i] is the count for names[i].

Two minutes

Change i < stock.length to i <= stock.length and run it. The total becomes NaN, because the extra pass reads undefined and 233 + undefined is not a number. Change it back.

Useful array methods

A method is a function attached to a value, called with a dot.

Method Does Example Result
.push(v) add to the end low.push("LED red") array grows
.includes(v) is this value present? names.includes("LED red") true
.indexOf(v) at which index? (-1 if absent) names.indexOf("LED red") 3
.join(sep) make one string low.join(", ") "a, b"
.slice(a, b) copy items a up to (not including) b names.slice(0, 2) first two
const lowStock = ["Resistor 330", "LED red"];
console.log(lowStock.join(", "));
console.log(names.indexOf("LED red"));
Resistor 330, LED red
3

.join() turns a list into a readable report line.

Walkthrough

Create inventory-report.js. Two arrays that line up by index: one name and one stock count per position.

const names = ["Resistor 220", "Resistor 330", "Capacitor 100n", "LED red", "Diode 1N4148"];
const stock = [42, 8, 120, 3, 60];

let total = 0;
const lowStock = [];

for (let i = 0; i < names.length; i++) {
  total += stock[i];
  if (stock[i] < 10) {
    lowStock.push(names[i]);
  }
}

console.log("Components:", names.length);
console.log("Total units:", total);
console.log("Low stock:", lowStock.join(", "));

Run node inventory-report.js:

Components: 5
Total units: 233
Low stock: Resistor 330, LED red

One pass does two jobs: it adds to the accumulator every time, and pushes to lowStock only when the if (Day 17) matches. Check by hand — 42 + 8 + 120 + 3 + 60 = 233 — and confirm exactly the two counts under 10 were collected.

Checkpoint

Say why total is let and lowStock is const, given that both change during the loop. (total is reassigned to a new number each pass; lowStock is always the same array, with items added to it.)

Your turn

Deliverable: an array-based inventory report.

  1. In js-basics/, create inventory-report.js with your own two arrays of five components: names (strings) and stock (numbers). Same length, matching order.
  2. Log names.length, names[0], and names[names.length - 1] to prove your indexing.
  3. Use a classic for loop with an accumulator to compute total units. Verify it by hand.
  4. In the same loop, push every component whose stock is below 10 into a lowStock array.
  5. Print a formatted report: a header line, a for...of loop printing one line per name, the total, then lowStock.join(", "). If lowStock.length === 0, print "No low stock" instead.
  6. Use .includes() to check whether a specific component is in your inventory, and log the boolean answer.
  7. Change one stock number so a different component becomes low, rerun, and confirm the report changes without you editing the loop. That is the point of today.

Pair mode — after step 3 stalls, not before

"Give me hints to process this array without writing the final loop until I attempt it." Ask for hints, attempt the loop, then compare. Before accepting an AI-generated change, inspect the diff line by line, run your checks — here, the hand-computed total — and understand the behavior before you keep it. An unverified suggestion is not progress.

Common pitfalls

  • Starting at index 1. The first item is [0]. Counting from one skips it silently.
  • <= in the loop condition. One extra pass reads undefined and poisons totals with NaN.
  • Declaring the accumulator inside the loop. let total = 0 inside the braces resets it every pass; it must be declared outside.
  • Arrays that drift out of alignment. Adding a name without a matching stock number breaks every later stock[i]. Tomorrow's objects fix this.

Verify it yourself

Open today's reference, MDN's Dynamic scripting with JavaScript, and find its pages on arrays and on looping code.

  1. MDN documents .pop() alongside .push(). What does it do, and what does it return?
  2. Find MDN's description of for...of. Does it agree that you get values rather than indexes?

Write both answers as comments at the bottom of inventory-report.js.

The hour

  1. 0–5 min Recall

    Without notes, state yesterday’s main idea and one unresolved question.

  2. 5–20 min Learn

    Read only the listed concept notes and official reference sections needed today.

  3. 20–48 min Build

    Store five components and calculate total stock, low-stock items, and a formatted report.

  4. 48–55 min Explain and verify

    Run the result, inspect evidence, and explain the data/control flow in your own words.

  5. 55–60 min Quiz and commit

    Complete the quiz, record one lesson, and commit the verified change when applicable.

What to hand in

Deliverable

An array-based inventory report.

Working with AI today

AI as pair programmer

Define one small task, review the plan, inspect the diff, run checks, and explain every changed section.

Give me hints to process this array without writing the final loop until I attempt it.

References

End-of-day quiz

Q1 Which structure is suited to an ordered collection?
Q2 Which result best proves today’s work is complete?
Q3 Before accepting an AI-generated code change, what should you do?

Explain-back gate

Pass the quiz above to unlock completion.

Quiz + explain-back checks required.