Question
How to Loop Through a JavaScript Object: Keys, Values, and Entries
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"
};
p1andp2are 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...inloops through enumerable property namesObject.keys()gives you an array of keysObject.values()gives you an array of valuesObject.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 labelsObject.values()gives you just the contentsObject.entries()gives you both the label and the contents together
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.
keywill 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:
-
useris created with three properties:name: "Ava"age: 28role: "admin"
-
Object.entries(user)creates an array of pairs:
[["name", "Ava"], ["age", 28], ["role", "admin"]]
-
The
for...ofloop goes through that array one item at a time. -
On the first loop:
[key, value]becomes["name", "Ava"]keyis"name"valueis"Ava"- it prints
name: Ava
-
On the second loop:
keyis"age"valueis28- it prints
age: 28
-
On the third loop:
keyis"role"valueis"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}`);
});
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
| Approach | What it returns or loops over | Best when | Notes |
|---|---|---|---|
for...in | Property names | You want a simple loop over keys | May include inherited enumerable properties |
Object.keys(obj) | Array of keys | You need keys only or want array methods | Very common and predictable |
Object.values(obj) | Array of values | You only care about values | Ignores keys |
Object.entries(obj) | Array of [key, value] pairs | You need both key and value | Often the clearest modern option |
for...in vs Object.entries()
| Feature | for...in | Object.entries() |
|---|---|---|
| Gives keys | Yes | Yes |
| Gives values directly | No, you must use obj[key] | Yes |
| Can include inherited properties | Yes | No, only own enumerable properties |
Works well with for...of | No | Yes |
| Beginner readability | Okay | Very 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...incarefully, especially when inheritance may matter
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]whenkeyis a variable - Plain objects are not directly iterable with
for...of for...incan include inherited enumerable propertiesObject.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);
}
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
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.