SECTION 1
Historical Context & Motivation
From the earliest days of programming, developers needed ways to store and retrieve data by name rather than by position. Arrays are great when you have a numbered list, but what about when you want to look up a value by a descriptive label—like a student's grade by their name? This need led to the development of associative data structures, which pair keys with values. In JavaScript, the plain object became the primary way to represent these key-value pairs. As programs grew more complex, developers needed reliable ways to iterate (loop) over every entry in an object so they could search, filter, and compute results automatically.
1995 • JavaScript Is Born
for...in loop were part of the language from day one, giving developers a way to iterate over object properties.2009 • ES5 Adds Object.keys()
Object.keys(), which returns an array of an object's own property names. This made iteration safer and more predictable than for...in.2015 • ES6 Brings Object.values() & Object.entries()
Object.values() and Object.entries(), making it trivial to access just the values or both keys and values as paired arrays.2017 • Modern Iteration Patterns Mature
Object.entries() with forEach, map, and reduce became standard practice in professional JavaScript.Today, the central question is straightforward: given an object full of data, how do we visit every key-value pair and use those values to calculate something useful? That is exactly what this lesson will teach you to do.
SECTION 2
Core Principles & Definitions
Before you can loop over an object, you need a solid understanding of its structure. A JavaScript object is a collection of properties, where each property has a key (always a string or symbol) and a corresponding value (which can be any data type). Iteration means systematically visiting each property one at a time so you can read or use it.
Object.keys(obj)
for, forEach, or any array method.Object.values(obj)
Object.entries(obj)
for...in Loop
hasOwnProperty() to filter.KEY TAKEAWAY
Object.keys() reads all the labels, Object.values() pulls out all the documents, and Object.entries() opens each drawer so you see the label and document together.SECTION 3
Visual Explanation
scores) on the left with four key-value pairs. The three arrows lead to the outputs of Object.keys() (cyan), Object.values() (pink), and Object.entries() (amber). Notice how each method extracts a different slice of the object's data.The visual above captures the most important insight: all three methods convert an object's data into an array. Once you have an array, you can use familiar loop techniques—for loops, forEach, or for...of—to process each element. This bridge from object to array is the key pattern you'll use repeatedly.
SECTION 4
How Each Iteration Method Works
Pattern 1: for...in Loop
The for...in loop is the oldest approach. On each iteration the loop variable receives the key (as a string), and you use bracket notation to access the corresponding value. Here is the general shape:
FOR...IN SYNTAX
key — the property name (string). obj[key] — the corresponding value.
Watch Out
for...in also visits inherited properties from the prototype chain. In most cases you should guard with if (obj.hasOwnProperty(key)) or prefer Object.keys() which only returns the object's own properties.Pattern 2: Object.keys() + forEach
OBJECT.KEYS + FOREACH
First, Object.keys(obj) produces an array of key strings. Then forEach runs a callback function once per key.
Pattern 3: Object.entries() + Destructuring
OBJECT.ENTRIES + FOR...OF
Each entry is a small array [key, value]. The square brackets on the left side destructure each pair into two named variables, giving you clean access to both the key and the value.
Pattern 4: Object.values() for Totals
SUMMING VALUES WITH REDUCE
Object.values(obj) extracts only the values. reduce accumulates them into a single total, starting from 0.
SECTION 5
Common Iteration Tasks
Now that you know the four main iteration patterns, let's look at the typical tasks you'll perform when iterating over objects. The diagram below illustrates how a single data object can be processed in several different ways depending on what result you need.
inventory object and branches into three common tasks: summing values, finding a maximum, and filtering entries. Below each task is the recommended method to use.| Task | Best Method | Why? |
|---|---|---|
| Sum / Average all values | Object.values() | You only need the numbers, not the keys. |
| Find the key with the highest value | Object.entries() | You need both the key and value to compare and report the winner. |
| Build a new object with transformed values | Object.entries() | You iterate key-value pairs and reconstruct a modified object. |
| List all property names | Object.keys() | Values are irrelevant; you just need the key strings. |
| Count how many values meet a condition | Object.values() | Filter or reduce the values array directly. |
Choosing the right iteration method based on your task
SECTION 6
Worked Example — Computing a Class Average
Suppose you have an object that stores test scores for every student in a class. Your goal: calculate the class average and identify which students scored above it. Let's walk through the solution step by step.
Calculate the Class Average and Find Above-Average Students
- 1
Step 1 — Define the Data Object
Start with the object:const scores = { alice: 92, bob: 85, carol: 97, dave: 78, eve: 88 };This object has five properties. Each key is a student name; each value is their test score. - 2
Step 2 — Extract the Values
Useconst vals = Object.values(scores);to produce the array[92, 85, 97, 78, 88]. We need only the numbers to compute the total and count.vals = [92, 85, 97, 78, 88] - 3
Step 3 — Compute the Sum
Useconst total = vals.reduce((sum, v) => sum + v, 0);which adds each value to an accumulator starting at 0. The reduce walks through 92 + 85 + 97 + 78 + 88.total = 440 - 4
Step 4 — Compute the Average
Divide the total by the number of students:const avg = total / vals.length;which gives 440 ÷ 5.avg = 88 - 5
Step 5 — Find Above-Average Students
Now we need both names and scores, so we switch toObject.entries():const aboveAvg = Object.entries(scores).filter(([name, score]) => score > avg);This destructures each pair and keeps only those where the score exceeds 88.aboveAvg = [["alice", 92], ["carol", 97]] - 6
Step 6 — Format the Output
Map the filtered entries to readable strings:aboveAvg.map(([name, score]) => `${name}: ${score}`). The final result is an array of formatted strings identifying who beat the class average of 88.["alice: 92", "carol: 97"]
SECTION 7
Comparing Iteration Approaches
Each iteration method has strengths and trade-offs. The table below compares the four approaches you've learned so you can choose wisely in your own projects.
| Method | Returns | Strengths | Limitations |
|---|---|---|---|
for...in | Keys (one at a time) | Simple syntax; no extra array created | Iterates inherited properties; not chainable with array methods |
Object.keys() | Array of key strings | Only own properties; chainable with forEach, map, etc. | You must use bracket notation to access values |
Object.values() | Array of values | Direct access to values; great for numeric computations | You lose the key names entirely |
Object.entries() | Array of [key, value] pairs | Full access to both; supports destructuring | Slightly more verbose syntax |
Side-by-side comparison of JavaScript object iteration methods
CHOOSING YOUR METHOD
SECTION 8
Connection to Advanced Concepts
Mastering object iteration is a stepping stone to several more advanced topics in JavaScript and computer science. The patterns you've learned here form the foundation for working with JSON data from APIs, Map and Set data structures, and functional programming paradigms that process collections of data in powerful, concise ways.
| What You Know Now | What Comes Next |
|---|---|
| Iterating plain objects with Object.keys / values / entries | Using the Map data structure, which has built-in iterators and maintains insertion order |
| Using reduce to sum values | Chaining map → filter → reduce for complex data pipelines |
| Accessing key-value pairs in a single object | Iterating arrays of objects (e.g., JSON responses) with nested loops |
| Destructuring [key, value] pairs | Deep destructuring of nested objects and default parameters |
From current skills to advanced JavaScript topics
When you move on to working with APIs, you'll fetch JSON data that arrives as nested objects and arrays. The iteration skills you've built here will let you extract exactly the information you need from those responses. Similarly, if you take a course on data structures and algorithms, you'll find that many problems—like counting word frequencies or building lookup tables—are solved by iterating over object-like structures.
SECTION 9
Practice Problems
Question 1: CONCEPTUAL
Object.keys() and Object.entries(). When would you choose one over the other?Show answer
Object.keys() returns an array containing only the property names (keys) of an object, while Object.entries() returns an array of [key, value] pairs. You'd choose Object.keys() when you only need the names (for example, listing all the fields in a form). You'd choose Object.entries() when your logic requires both the key and the value simultaneously (for example, printing a report of student names and their grades).Question 2: BASIC CALCULATION
const prices = { shirt: 25, hat: 15, shoes: 60, socks: 8 };, write code using Object.values() to compute the total cost of all items. What is the result?Show answer
const total = Object.values(prices).reduce((sum, v) => sum + v, 0); This extracts the values [25, 15, 60, 8] and reduces them to a single sum. The computation is 25 + 15 + 60 + 8 = 108. So total equals 108. Alternatively, you could use a for...of loop over Object.values(prices) and add to an accumulator variable.Question 3: INTERMEDIATE
const temps = { mon: 72, tue: 68, wed: 75, thu: 80, fri: 65 };, write code that creates a new object where each value is converted from Fahrenheit to Celsius using the formula C = (F − 32) × 5 ÷ 9. Round each result to one decimal place.Show answer
Object.entries() to iterate and Object.fromEntries() to build the result: const celsius = Object.fromEntries(Object.entries(temps).map(([day, f]) => [day, Math.round(((f - 32) * 5 / 9) * 10) / 10])); For Monday: (72 − 32) × 5 ÷ 9 = 22.2 °C. The final object is { mon: 22.2, tue: 20, wed: 23.9, thu: 26.7, fri: 18.3 }. The key pattern is: entries in → transform → entries out via Object.fromEntries().Question 4: APPLIED
const quiz = { ana: 91, ben: 74, cara: 85, dan: 68, ella: 95, finn: 82 }; Write a function gradeReport(scores) that returns an object with three properties: average (rounded to one decimal), highest (the name of the top scorer), and passing (an array of names with scores ≥ 80).Show answer
function gradeReport(scores) { const vals = Object.values(scores); const avg = Math.round((vals.reduce((s,v) => s+v, 0) / vals.length) * 10) / 10; let highest = ''; let maxScore = -Infinity; for (const [name, score] of Object.entries(scores)) { if (score > maxScore) { maxScore = score; highest = name; } } const passing = Object.entries(scores).filter(([n, s]) => s >= 80).map(([n]) => n); return { average: avg, highest, passing }; } For the given quiz data, the average is (91+74+85+68+95+82) ÷ 6 = 82.5. The highest scorer is ella with 95. The passing students are ana, cara, ella, and finn. The function demonstrates combining Object.values() for the average and Object.entries() for tasks that need both name and score.Question 5: CRITICAL THINKING
const warehouseA = { bolts: 300, nuts: 450, washers: 200 }; and const warehouseB = { bolts: 150, screws: 500, washers: 100 }; Write code that creates a merged object combined where each key's value is the total across both warehouses. Items that appear in only one warehouse should still be included. Explain your approach.Show answer
const combined = {}; for (const [item, qty] of Object.entries(warehouseA)) { combined[item] = (combined[item] || 0) + qty; } for (const [item, qty] of Object.entries(warehouseB)) { combined[item] = (combined[item] || 0) + qty; } The result is { bolts: 450, nuts: 450, washers: 300, screws: 500 }. The expression (combined[item] || 0) handles items that don't yet exist in the combined object by defaulting to 0 before adding. This pattern—initialize-or-accumulate—is a fundamental technique you'll see in frequency counts, vote tallies, and inventory management. You could also generalize this into a function that accepts any number of warehouse objects using rest parameters.SUMMARY
Lesson Summary
Summary
JavaScript objects store data as key-value pairs, and iterating over them is one of the most common tasks in programming. You learned four approaches: for...in loops through property names but may include inherited properties; Object.keys() safely returns an array of own property names; Object.values() returns just the values for numeric computations like sums and averages; and Object.entries() returns [key, value] pairs when you need both pieces of information.
The crucial insight is that all three Object.* methods convert an object into an array, enabling you to use familiar array methods like forEach, map, filter, and reduce. By choosing the right method for each task—keys when you need labels, values when you need data, entries when you need both—you can write clean, readable code that solves real-world problems like computing averages, finding maximums, filtering data, and merging collections.