JavaScript • Control Flow

Iterating Objects — Iterate object keys/entries (Object.keys/entries) (intro)

Learn how to loop through JavaScript objects by extracting their keys, values, and entries into iterable arrays.

JavaScript emblem with code brackets, braces, and a code file.
Inside this lesson 10 sections 5 questions 7 figures

SECTION 1

Historical Context & Motivation

JavaScript was created in 1995 as a simple scripting language for web browsers, but it quickly grew into something much more powerful. From the very beginning, objects were a core part of the language — they let developers store data as key-value pairs, much like a dictionary maps words to definitions. However, for many years, the only built-in way to loop through an object's properties was the for...in loop, which had some confusing quirks. As JavaScript matured, the language designers introduced cleaner, more predictable methods for iterating over objects.

1995 • JavaScript Created

Brendan Eich creates JavaScript in just 10 days at Netscape. Objects are a fundamental data structure from day one, but iteration tools are limited.

1999 • ECMAScript 3 — for...in Loop

The for...in loop becomes the standard way to iterate over object properties. However, it also traverses inherited properties from the prototype chain, causing unexpected bugs.

2011 • ES5 — Object.keys() Introduced

ECMAScript 5 introduces Object.keys(), which returns an array of an object's own enumerable property names. This gives developers a clean, safe way to iterate object keys.

2017 • ES8 — Object.entries() & Object.values()

ECMAScript 2017 adds Object.entries() and Object.values(), completing the trio of static methods for converting objects into iterable arrays of keys, values, or key-value pairs.

The central problem is straightforward: arrays in JavaScript are easy to loop through with for loops, .forEach(), or for...of, but objects are not arrays. So how do you systematically visit every property in an object? The answer lies in converting object properties into arrays that you can then iterate with familiar array methods.

SECTION 2

Core Principles & Definitions

Before diving into code, let's clarify the key ideas behind iterating objects. JavaScript objects store data in key-value pairs, where each key (also called a property name) is a string that maps to a corresponding value. The three static methods — Object.keys(), Object.values(), and Object.entries() — each extract a different piece of that key-value relationship and return it as an array.

1

Object.keys()

Returns an array of strings representing the object's own enumerable property names (the keys). Example: ["name", "age", "grade"]
2

Object.values()

Returns an array containing the object's own enumerable property values only. Example: ["Alice", 16, "11th"]
3

Object.entries()

Returns an array of [key, value] pairs, each represented as a two-element array. Example: [["name", "Alice"], ["age", 16]]
4

Own vs. Inherited Properties

All three methods return only the object's own properties — not properties inherited from the prototype chain. This avoids the common pitfall of for...in loops.
✦

KEY TAKEAWAY

Think of a JavaScript object like a school locker wall. Each locker has a number (the key) and stuff inside (the value). Object.keys() gives you a list of all the locker numbers. Object.values() gives you everything inside the lockers. Object.entries() gives you each locker number paired with its contents.

SECTION 3

Visual Explanation

The following diagram shows how a single JavaScript object is transformed into three different array outputs by each of the static methods. Notice how each method extracts a different slice of the same underlying data.

Object → Arrays via Object.keys / values / entriesstudent (Object)name: "Alice"age: 16grade: "11th"Object.keys()Object.values()Object.entries()Array of Keys[0] "name"[1] "age"[2] "grade"Array of Values[0] "Alice"[1] 16[2] "11th"Array of Entries[0] ["name", "Alice"][1] ["age", 16][2] ["grade", "11th"]Each method returns a standard JavaScript array you can loop with for...of, .forEach(), .map(), etc.
The center object student contains three key-value pairs. The three arrows show how each static method extracts different information: keys only (cyan), values only (pink), or paired entries (amber).

The key insight from this diagram is that all three methods convert the object into a regular array. Once you have an array, you can use any array iteration method you already know — for...of, .forEach(), .map(), and more. This "convert then iterate" strategy is the foundation of object iteration in modern JavaScript.

SECTION 4

How Each Method Works

Object.keys() — Get Property Names

Object.keys(obj) accepts an object and returns an array of strings. Each string is one of the object's own enumerable property names. The order of keys in the returned array matches the order in which properties were added to the object (with integer-like keys sorted first).

SYNTAX — OBJECT.KEYS

constkeysArray=Object.keys(myObject);const keysArray = Object.keys( myObject );

Returns: string[] — an array of property name strings.

Object.values() — Get Property Values

Object.values(obj) works the same way, but instead of returning the property names it returns the corresponding values. Values can be of any type — strings, numbers, booleans, other objects, or even functions.

SYNTAX — OBJECT.VALUES

constvaluesArray=Object.values(myObject);const valuesArray = Object.values( myObject );

Returns: any[] — an array of the property values in the same order as Object.keys().

Object.entries() — Get Key-Value Pairs

Object.entries(obj) combines both pieces: it returns an array where each element is itself a two-element array — [key, value]. This is especially powerful when combined with destructuring in a for...of loop, which lets you unpack the key and value into separate variables in one line.

SYNTAX — OBJECT.ENTRIES WITH DESTRUCTURING

for(const[key,value]ofObject.entries(myObject))...for (const [key, value] of Object.entries(myObject)) { ... }

The square brackets [key, value] use array destructuring to assign the first element (the key) and the second element (the value) to separate variables automatically.

SECTION 5

Common Iteration Patterns

Now that you know the three methods, let's look at the most common patterns developers use to loop through objects. The diagram below shows each method paired with the iteration technique that works best with it.

Common Iteration PatternsPattern 1: forEach + keysObject.keys(obj) .forEach(key => { console.log( key, obj[key] ); });Use when you need keys andbracket notation for valuesPattern 2: for...of + entriesfor (const [k, v] of Object.entries( obj)) { console.log(k, v);}Cleanest approach — get keyand value via destructuringPattern 3: map + entriesconst result = Object.entries(obj) .map(([k, v]) => `${k}: ${v}` );Use when you need totransform data into new arrayExample Output (for all three patterns)Given:const obj = { name: "Alice", age: 16, grade: "11th" };Pattern 1 output:name Alice → age 16 → grade 11thPattern 2 output:name Alice → age 16 → grade 11thPattern 3 output:["name: Alice", "age: 16", "grade: 11th"]Patterns 1 & 2 log each pair; Pattern 3 builds a new array of formatted strings.
Three common iteration patterns shown side-by-side. Pattern 1 uses Object.keys() with .forEach(). Pattern 2 uses Object.entries() with for...of and destructuring. Pattern 3 uses Object.entries() with .map() to transform data.
💡

Destructuring Tip

When you see const [key, value] inside a for...of loop, the square brackets are performing array destructuring. Each entry from Object.entries() is a two-element array like ["name", "Alice"], and destructuring automatically assigns the first element to key and the second to value.

SECTION 6

Worked Example

Let's walk through a realistic scenario. Imagine you have an object representing a student's test scores, and you want to calculate their average and print each subject with its score.

Calculate Average Test Score from an Object

  1. 1

    Step 1 — Define the Object

    We start with a scores object where each key is a subject name and each value is a numeric score: const scores = { math: 92, english: 88, science: 95, history: 78 };
    Object with 4 key-value pairs
  2. 2

    Step 2 — Extract the Values

    Since we need the numeric scores to compute an average, we use Object.values() to get an array of just the numbers: const vals = Object.values(scores); // [92, 88, 95, 78]
    [92, 88, 95, 78]
  3. 3

    Step 3 — Sum the Values

    We can use .reduce() to add all scores together: const total = vals.reduce((sum, score) => sum + score, 0); // 353
    total = 353
  4. 4

    Step 4 — Calculate the Average

    Divide the total by the number of subjects. We can get the count from Object.keys(scores).length: const avg = total / Object.keys(scores).length; // 88.25
    average = 88.25
  5. 5

    Step 5 — Print Each Subject with Its Score

    Now use Object.entries() with a for...of loop to print each subject alongside its score: for (const [subject, score] of Object.entries(scores)) { console.log(`${subject}: ${score}`); } This outputs: math: 92, english: 88, science: 95, history: 78.
    Each subject and score printed on its own line

SECTION 7

Comparing Object Iteration Methods

You now know three static methods for iterating objects, but JavaScript also has the older for...in loop. Understanding how they compare will help you choose the right tool for each situation.

Featurefor...inObject.keys()Object.entries()
ReturnsKeys (one at a time in loop)Array of key stringsArray of [key, value] pairs
Includes inherited properties?YesNo (own only)No (own only)
Works with array methods?NoYes (.map, .filter, etc.)Yes (.map, .filter, etc.)
Supports destructuring?NoNot directlyYes — [key, value]
Best forLegacy code, prototype inspectionWhen you only need keysWhen you need both keys and values

Comparison of object iteration approaches in JavaScript

✦

KEY TAKEAWAY

In modern JavaScript, Object.keys() and Object.entries() are almost always preferred over for...in because they skip inherited properties and return real arrays you can chain with .map(), .filter(), and other array methods. Think of for...in like an older phone — it still works, but the newer models have better features and fewer bugs.

SECTION 8

Connection to Advanced Concepts

The methods you learned here are building blocks for more advanced JavaScript patterns. As you progress, you'll encounter situations where these techniques combine with other tools to solve complex problems.

What You Learned TodayWhere It Leads
Object.entries() to convert object → arrayObject.fromEntries() converts array → object (the reverse)
Iterating flat objects with simple valuesRecursively iterating nested objects (objects inside objects)
Using .map() and .filter() on entriesTransforming API response data in real-world web apps
Own enumerable properties onlySymbols, non-enumerable properties, and Reflect.ownKeys()

How today's concepts connect to advanced JavaScript

One particularly useful advanced pattern is using Object.entries() combined with .filter() and Object.fromEntries() to create a new object containing only the properties that pass a test. This is essentially "filtering an object," which JavaScript doesn't support natively but becomes easy with these tools.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain the difference between what Object.keys() and Object.entries() return. Why would you choose one over the other?
Show answer
Object.keys() returns an array of strings — just the property names (keys) of the object. Object.entries() returns an array of two-element arrays, where each inner array contains a key and its corresponding value. You would choose Object.keys() when you only need property names (for example, to count properties or check if a key exists). You would choose Object.entries() when you need both the key and the value together, especially since you can destructure each entry in a for...of loop for cleaner code.

Question 2: BASIC CALCULATION

Given const pet = { species: "dog", name: "Max", age: 5 };, what does Object.keys(pet) return? What does Object.values(pet) return?
Show answer
Object.keys(pet) returns ["species", "name", "age"] — an array of the three property name strings. Object.values(pet) returns ["dog", "Max", 5] — an array containing the values in the same order as the keys. Notice that values can be different types (strings and numbers mixed together).

Question 3: INTERMEDIATE

Write a code snippet using Object.entries() and a for...of loop that takes the object const prices = { apple: 1.20, banana: 0.50, cherry: 3.00 }; and logs each fruit with a 10% price increase in the format "apple: $1.32".
Show answer
The solution uses destructuring inside the for...of loop: for (const [fruit, price] of Object.entries(prices)) { console.log(`${fruit}: $${(price * 1.10).toFixed(2)}`); } Here, [fruit, price] destructures each entry. We multiply the price by 1.10 to add 10% and use .toFixed(2) to format the number to two decimal places. The output would be: apple: $1.32, banana: $0.55, cherry: $3.30.

Question 4: APPLIED

A teacher stores student attendance in an object: const attendance = { Alice: 18, Bob: 12, Carol: 20, Dave: 9 }; where each value is the number of days attended out of 20. Using Object.entries() and array methods, write code that creates an array of names of students who attended fewer than 15 days.
Show answer
You can chain .filter() and .map() on the entries array: const lowAttendance = Object.entries(attendance).filter(([name, days]) => days < 15).map(([name, days]) => name); First, .filter() keeps only entries where days is less than 15 (Bob with 12 and Dave with 9). Then .map() extracts just the name from each remaining entry. The result is ["Bob", "Dave"].

Question 5: CRITICAL THINKING

Consider two approaches to iterating an object: (A) using for...in with hasOwnProperty() checks, and (B) using Object.keys() with .forEach(). Under what circumstances might approach (A) still be useful? Discuss readability, safety, and potential edge cases.
Show answer
Approach (B) with Object.keys() is generally more readable and safer because it automatically excludes inherited properties. Approach (A) with for...in might still be useful when you intentionally want to inspect inherited properties — for example, when debugging a prototype chain or when writing a utility function that needs to see all enumerable properties across the inheritance hierarchy. However, in most everyday code, approach (B) is preferred because it produces cleaner code, avoids the boilerplate of the hasOwnProperty() check, and returns a real array that supports chaining with .filter(), .map(), and other array methods.

SUMMARY

Lesson Summary

Summary

JavaScript objects store data as key-value pairs, but unlike arrays, they aren't directly iterable. The solution is to convert them into arrays using three static methods: Object.keys() returns an array of property name strings, Object.values() returns an array of property values, and Object.entries() returns an array of [key, value] pairs. All three methods return only the object's own enumerable properties, avoiding the inherited-property pitfalls of the older for...in loop.

Once you have an array, you can use any standard array iteration method — for...of, .forEach(), .map(), or .filter(). The most powerful combination is Object.entries() with destructuring in a for...of loop, which gives you clean access to both keys and values in every iteration.

Varsity Tutors • JavaScript • Iterating Objects — Iterate object keys/entries (Object.keys/entries) (intro)