Objects inside objects
Real data nests. A student has grades, grades have subjects:
const student = { name: "Ada", grades: { math: 95, cs: 99 } }; console.log(student.grades.math); // 95
Chain the dots one level at a time. If a middle link might be missing, student.grades?.math answers undefined instead of crashing (the optional chaining operator ?.).
Looping over properties
Objects are not directly for...of iterable. Instead, three helpers turn an object into an array first:
Object.keys(obj)→ array of key stringsObject.values(obj)→ array of valuesObject.entries(obj)→ array of[key, value]pairs
With entries you can unpack each pair right in the loop header, like Python's for k, v in d.items():
for (const [subject, grade] of Object.entries(student.grades)) { console.log(`${subject}: ${grade}`); }
The [subject, grade] part is called destructuring: it splits a two-item array into two named variables.
Reaching into a nest and looping over it
Three techniques on one nested object: chained dots to read a value two levels down, Object.entries to drive a loop over the inner object, and Object.keys to list the outer property names.
const student = { name: "Ada", grades: { math: 95, cs: 99 } }; console.log(student.grades.math); for (const [subject, grade] of Object.entries(student.grades)) { console.log(`${subject}: ${grade}`); } console.log(Object.keys(student));
Output
95 math: 95 cs: 99 [ 'name', 'grades' ]
student.grades.math is read left to right, one dot at a time: student gives an object, .grades gives the inner object, and .math gives the number. The loop produces two lines because grades has two properties, and the pair [subject, grade] arrives already split into two usable names.
The final line is a reminder about levels. Object.keys(student) lists only the top-level names, name and grades, and does not descend into the nested object. Every one of these helpers works on exactly one level at a time.
One line of output per property
Formatting a price list is the everyday use of Object.entries, since both halves of each pair are needed, the item name for the label and the price for the value.
const prices = { coffee: 3, tea: 2.5 }; for (const [item, price] of Object.entries(prices)) { console.log(`${item} costs $${price}`); }
Output
coffee costs $3 tea costs $2.5
The double dollar sign in $${price} looks like a typo and is not. The first $ is an ordinary character being printed, part of the money format, and the second one belongs to the ${...} placeholder that follows it. Reading it as $ plus ${price} makes it obvious.
Note also that 2.5 prints as 2.5 rather than 2.50. Numbers carry no formatting of their own, so aligning money to two decimal places is a separate job, handled by the toFixed method covered in lesson 8-2.
Totaling values when the keys do not matter
Summing a cart needs the prices and nothing else, so Object.values is the right helper. It hands back a plain array, which the for...of loop from lesson 3-3 then walks with the accumulator pattern.
const cart = { coffee: 3, bagel: 2.5, juice: 4 }; let total = 0; for (const price of Object.values(cart)) { total = total + price; } console.log(total);
Output
9.5Object.values(cart) is the array [3, 2.5, 4], and once that array exists nothing about the loop is object-specific. That is the mental model to carry away from these three helpers: they convert an object into an array so that everything you already know about arrays applies.
Choosing between them comes down to what the body of the loop needs.
| Helper | Returns for {coffee: 3, tea: 2.5} | Use when |
|---|---|---|
Object.keys | ['coffee', 'tea'] | only the names matter |
Object.values | [3, 2.5] | only the contents matter |
Object.entries | [['coffee', 3], ['tea', 2.5]] | both matter |
Getting key and value together
The call that returns an array of [key, value] pairs is Object.entries(obj), and it is the closest match to Python's dict.items().
Its pairs are ready for destructuring in a for...of header, which is why for (const [k, v] of Object.entries(obj)) reads so much like the Python loop it replaces. The two neighbouring helpers each give you half of that: Object.keys returns only the names and Object.values only the contents. There is no .items() method on a JavaScript object, so that spelling is one to unlearn coming from Python.