JS Sketchbooksee JavaScript think ✏️
← back to phase 4

4.8 — Iterating collections

You already know one way to walk an array: lesson 2.6's for (let i = 0; i < cart.length; i++). It works — and it makes you manage a counter, remember < length, and type cart[i] everywhere, just to say “each element, please.”

Collections deserve loops that speak collection: for...of hands you each array element; for...in hands you each object key.

And Object.keys / values / entries convert an object into arrays — the bridge that lets every array tool (including next lesson's big three) work on objects too.

watch it happen
const cart = ["pen", "mug", "fan"];

for (const item of cart) {
  console.log(item);
}

const prices = { pen: 2, mug: 9 };

for (const key in prices) {
  console.log(key);
}

console.log(Object.keys(prices));
console.log(Object.values(prices));
console.log(Object.entries(prices));

for (const item of cart) — read it as “for each element of cart.” No counter, no length check, no cart[i]: the loop feeds elements to item one at a time, in order. Use it whenever you want the elements and don’t care about their indexes. (Need the index too? The classic 2.6 for loop is still the tool.)

cart — an array: ordered elements"pen"0"mug"1"fan"2for...of visits ELEMENTS, in order — no index bookkeepingconsole (latest)(nothing printed yet)
under the hood

The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”

for...of works on anything iterable — arrays, strings (character by character), and two structures arriving in 4.12 (Map and Set).

Plain objects are not iterable — that's why they need for...in or the Object.* converters instead, and why for (const x of {}) throws a TypeError.

The three converters return plain arrays, built fresh at that moment — snapshots, not live views. And a subtle everyday win: Object.keys(obj).length is how you count an object's properties, since objects have no .length of their own.

All of today's loops read; none of them copy. The loop variable receives what the collection holds. For elements that are objects, that is an arrow (4.6 forever): mutate item.done = true inside a loop and you've changed the real thing.

your turn

⌨️ total the receipt, whatever it holds

A café receipt arrives as an object — item names as keys, prices as values. Total it by LOOPING, so the same code still works when tomorrow’s receipt has 40 items.

requirements:

  • Create receipt: coffee = 120, cake = 80, water = 40.
  • Compute the total by iterating over the object's values — any of today's tools works. No arithmetic with hand-typed prices.
  • Print the total.

when you press RUN, the console must show exactly:

240

✏️ Quick check 1

What prints on the FIRST lap? Type it exactly:

const xs = ["a", "b", "c"];
for (const v of xs) {
  console.log(v);
}

✏️ Quick check 2

What prints on the FIRST lap? Type it exactly:

const obj = { x: 1, y: 2 };
for (const k in obj) {
  console.log(k);
}

✏️ Quick check 3

Type exactly what this prints:

const cfg = { a: 1, b: 2, c: 3 };
console.log(Object.keys(cfg).length);
teach it back

🗣️ Now teach it back

A friend wrote for (const x in ["a","b"]) and got confused by what x was. Explain the difference between for...of and for...in, which belongs to which collection — and how to loop over an object’s VALUES.

Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.

a few sentences, minimum — you’ve got this
to remember
for...of → array ELEMENTS in order (no counters); for...in → object KEYS (as strings).
Object.keys / values / entries snapshot an object into arrays — entries gives [key, value] pairs, the bridge to array tools.
Objects have no .length: count properties with Object.keys(obj).length.
next: 4.9 map / filter / reduce →