Question

How to Loop Through a JavaScript Object: Keys, Values, and Entries

javascriptloopsfor-loopeach

Question

I have a JavaScript object like this:

const p = {
  p1: "value1",
  p2: "value2",
  p3: "value3"
};

How can I loop through all of p's properties (p1, p2, p3, and so on) and access both their keys and values?

Short Answer

By the end of this page, you will understand how to iterate over a JavaScript object's properties and access its keys and values. You will learn the most common approaches, when to use each one, and how to avoid common mistakes such as iterating over inherited properties.

Concept

In JavaScript, an object stores data as key-value pairs. For example, in this object:

const p = {
  p1: "value1",
  p2: "value2"
};
  • p1 and p2 are the keys
  • "value1" and "value2" are the values

Looping through an object means visiting each property one by one so you can read or use its data.

This matters because objects are everywhere in JavaScript:

  • API responses are often objects
  • Configuration settings are often objects
  • Form data may be stored in objects
  • Lookup tables and grouped data are commonly represented as objects

There are several ways to iterate through an object, and each has a slightly different purpose:

  • for...in loops through enumerable property names
  • Object.keys() gives you an array of keys
  • Object.values() gives you an array of values
  • Object.entries() gives you an array of [key, value] pairs

For most modern JavaScript code, Object.entries() or Object.keys() is often the clearest choice because they work well with array methods and avoid some of the pitfalls of for...in.

Mental Model

Think of a JavaScript object like a set of labeled drawers:

  • the label on each drawer is the key
  • the item inside the drawer is the value

Looping through the object means opening each drawer one at a time:

  • first read the label
  • then read what is inside

Different JavaScript methods give you different ways to inspect the drawers:

  • Object.keys() gives you just the labels
  • Object.values() gives you just the contents
  • Object.entries() gives you both the label and the contents together
Take Quiz

Syntax and Examples

Using for...in

const p = {
  p1: "value1",
  p2: "value2",
  p3: "value3"
};

for (const key in p) {
  console.log(key, p[key]);
}

This prints each property name and its value.

  • key will be "p1", "p2", "p3"
  • p[key] accesses the matching value

Safer for...in with own-property check

const p = {
  p1: "value1",
  p2: "value2",
  p3: "value3"
};

for (const key in p) {
  if (Object.hasOwn(p, key)) {
    console.log(key, p[key]);
  }
}

This avoids iterating over inherited properties.

Using Object.keys()

const p = {
  p1: "value1",
  p2: "value2",
  p3: "value3"
};

Object.keys(p).forEach((key) => {
  console.log(key, p[key]);
});

Object.keys(p) returns:

["p1", "p2", "p3"]

Using Object.values()

const p = {
  p1: "value1",
  p2: "value2",
  p3: "value3"
};

Object.values(p).forEach((value) => {
  console.log(value);
});

This is useful when you only care about values.

Using Object.entries()

const p = {
  p1: "value1",
  p2: "value2",
  p3: "value3"
};

for (const [key, value] of Object.entries(p)) {
  console.log(key, value);
}

This is one of the cleanest modern patterns because it gives you both the key and value at the same time.

Example output

p1 value1
p2 value2
p3 value3

In beginner-friendly code, Object.entries() is often easiest to read when you need both parts.

Step by Step Execution

Consider this example:

const user = {
  name: "Ava",
  age: 28,
  role: "admin"
};

for (const [key, value] of Object.entries(user)) {
  console.log(`${key}: ${value}`);
}

Here is what happens step by step:

  1. user is created with three properties:

    • name: "Ava"
    • age: 28
    • role: "admin"
  2. Object.entries(user) creates an array of pairs:

[["name", "Ava"], ["age", 28], ["role", "admin"]]
  1. The for...of loop goes through that array one item at a time.

  2. On the first loop:

    • [key, value] becomes ["name", "Ava"]
    • key is "name"
    • value is "Ava"
    • it prints name: Ava
  3. On the second loop:

    • key is "age"
    • value is 28
    • it prints age: 28
  4. On the third loop:

    • key is "role"
    • value is "admin"
    • it prints role: admin

Final output:

name: Ava
age: 28
role: admin

Real World Use Cases

Looping through objects is common in real programs.

Rendering data in a UI

You may receive settings or profile data as an object and want to display each field.

const profile = {
  username: "sam",
  country: "UK",
  plan: "pro"
};

for (const [key, value] of Object.entries(profile)) {
  console.log(`${key}: ${value}`);
}

Validating form input

const formData = {
  email: "test@example.com",
  password: "123456",
  agreeToTerms: true
};

for (const [field, value] of Object.entries(formData)) {
  if (value === "" || value === null) {
    console.log(`${field} is required`);
  }
}

Building query strings or request payloads

const params = {
  page: 1,
  sort: "name",
  active: true
};

for (const [key, value] of Object.entries(params)) {
  console.log(`${key}=${value}`);
}

Processing API responses

const scores = {
  math: 90,
  english: 85,
  science: 92
};

Object.entries(scores).forEach(([subject, score]) => {
  console.log(`${subject}: ${score}`);
});
Take Quiz

Real Codebase Usage

In real codebases, developers often combine object iteration with other useful patterns.

Validation and guard clauses

function validateUser(user) {
  for (const [key, value] of Object.entries(user)) {
    if (value === undefined || value === null) {
      return `${key} is missing`;
    }
  }

  return "User is valid";
}

This uses an early return to stop as soon as invalid data is found.

Transforming object data

Developers often convert an object into an array using Object.entries(), transform it, then convert it back.

const prices = {
  apple: 1,
  banana: 2
};

const updatedPrices = Object.fromEntries(
  Object.entries(prices).map(([key, value]) => [key, value * 2])
);

console.log(updatedPrices);

Filtering object properties

const settings = {
  darkMode: true,
  notifications: false,
  beta: true
};

const enabledSettings = Object.fromEntries(
  Object.entries(settings).filter(([key, value]) => value === true)
);

console.log(enabledSettings);

Configuration objects

Large applications often store options in objects and loop through them to apply defaults or validate values.

const config = {
  timeout: 5000,
  retries: 3,
  debug: false
};

for (const [key, value] of Object.entries(config)) {
  console.log(`Config ${key} = ${value}`);
}

Error reporting

const errors = {
  email: "Invalid email",
  password: "Too short"
};

for (const [field, message] of Object.entries(errors)) {
  console.log(`${field}: ${message}`);
}

Common Mistakes

1. Using dot notation with a variable key

Broken code:

const p = { p1: "value1" };

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

This prints undefined because p.key looks for a property literally named key.

Correct code:

for (const key in p) {
  console.log(p[key]);
}

Use bracket notation when the property name is stored in a variable.

2. Forgetting that for...in can include inherited properties

Broken idea:

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

This may loop over inherited enumerable properties too.

Safer version:

for (const key in p) {
  if (Object.hasOwn(p, key)) {
    console.log(key, p[key]);
  }
}

3. Trying to use for...of directly on an object

Broken code:

const p = { p1: "value1", p2: "value2" };

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

This fails because plain objects are not directly iterable.

Correct code:

for (const item of Object.entries(p)) {
  console.log(item);
}

4. Assuming objects behave like arrays

Objects use keys, not numeric indexes.

Broken code:

const p = { p1: "value1", p2: "value2" };
console.log(p[0]);

This usually gives undefined.

5. Modifying an object while iterating without thinking carefully

If you add or remove properties during a loop, the results may be confusing.

A safer approach is to iterate over a fixed list of keys first:

const keys = Object.keys(p);

for (const key of keys) {
  console.log(key, p[key]);
}

Comparisons

ApproachWhat it returns or loops overBest whenNotes
for...inProperty namesYou want a simple loop over keysMay include inherited enumerable properties
Object.keys(obj)Array of keysYou need keys only or want array methodsVery common and predictable
Object.values(obj)Array of valuesYou only care about valuesIgnores keys
Object.entries(obj)Array of [key, value] pairsYou need both key and valueOften the clearest modern option

for...in vs Object.entries()

Featurefor...inObject.entries()
Gives keysYesYes
Gives values directlyNo, you must use obj[key]Yes
Can include inherited propertiesYesNo, only own enumerable properties
Works well with for...ofNoYes
Beginner readabilityOkayVery good

Rule of thumb

  • Use Object.entries() when you need both key and value
  • Use Object.keys() when you only need keys
  • Use Object.values() when you only need values
  • Use for...in carefully, especially when inheritance may matter
Take Quiz

Cheat Sheet

const obj = {
  a: 1,
  b: 2
};

Get keys

Object.keys(obj); // ["a", "b"]

Get values

Object.values(obj); // [1, 2]

Get key-value pairs

Object.entries(obj); // [["a", 1], ["b", 2]]

Loop with for...in

for (const key in obj) {
  if (Object.hasOwn(obj, key)) {
    console.log(key, obj[key]);
  }
}

Loop with Object.keys()

Object.keys(obj).forEach((key) => {
  console.log(key, obj[key]);
});

Loop with Object.entries()

for (const [key, value] of Object.entries(obj)) {
  console.log(key, value);
}

Important rules

  • Use obj[key] when key is a variable
  • Plain objects are not directly iterable with for...of
  • for...in can include inherited enumerable properties
  • Object.entries() is often the clearest option for key-value loops

FAQ

How do I loop through keys and values in a JavaScript object?

Use Object.entries() with for...of:

for (const [key, value] of Object.entries(obj)) {
  console.log(key, value);
}

What is the difference between for...in and Object.keys()?

for...in loops through enumerable property names, including inherited ones. Object.keys() returns only the object's own enumerable keys.

Can I use for...of directly on an object?

No. Plain JavaScript objects are not directly iterable. Use Object.keys(), Object.values(), or Object.entries() first.

What is the best way to iterate over an object in modern JavaScript?

If you need both keys and values, Object.entries() is usually the cleanest and easiest to read.

Why do I need bracket notation like obj[key]?

Because key is a variable. Dot notation like obj.key looks for a property literally named key.

Does object property order matter when looping?

JavaScript does define property order for many common cases, but you should not rely on object iteration order unless your logic truly needs it and you understand the rules.

How do I loop through only values in an object?

Use Object.values():

for (const value of Object.values(obj)) {
  console.log(value);
}
Take Quiz

Mini Project

Description

Create a small utility that prints the contents of a product object in a readable format. This demonstrates how to iterate through an object's keys and values, which is a common task when displaying configuration, API data, or user-submitted content.

Goal

Build a function that loops through a JavaScript object and logs each key-value pair in a clear format.

Requirements

Requirement 1 Requirement 2 Requirement 3

Take Quiz

Keep learning

Related questions

View more