JS Object Keys, Values, and Entries Full Guide
Master Object.keys(), Object.values(), and Object.entries() in JavaScript. Learn how to iterate over objects, transform data, filter properties, and convert between objects and arrays with practical examples.
JavaScript objects do not have built-in array methods like map, filter, or reduce. To iterate over and transform object data, you first need to convert the object into an array using Object.keys(), Object.values(), or Object.entries(). These three methods are among the most frequently used tools in JavaScript development, powering everything from data transformation to UI rendering.
This guide covers all three methods with practical examples, shows how to combine them with array methods, and teaches common patterns for working with object data.
Object.keys()
Object.keys() returns an array of an object's own enumerable string property names:
const user = {
name: "Alice",
age: 28,
email: "alice@example.com",
role: "developer"
};
const keys = Object.keys(user);
console.log(keys);
// ["name", "age", "email", "role"]Counting Properties
const product = {
name: "Laptop",
price: 999,
brand: "TechBrand",
inStock: true
};
console.log(Object.keys(product).length); // 4Checking for Empty Objects
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
console.log(isEmpty({})); // true
console.log(isEmpty({ a: 1 })); // false
console.log(isEmpty(new Object())); // trueIterating with Object.keys
const scores = {
math: 92,
science: 88,
english: 95,
history: 78
};
Object.keys(scores).forEach(subject => {
console.log(`${subject}: ${scores[subject]}`);
});
// math: 92
// science: 88
// english: 95
// history: 78Object.values()
Object.values() returns an array of an object's own enumerable property values:
const user = {
name: "Alice",
age: 28,
email: "alice@example.com"
};
const values = Object.values(user);
console.log(values);
// ["Alice", 28, "alice@example.com"]Calculating with Values
const monthlyExpenses = {
rent: 1500,
food: 400,
transport: 120,
utilities: 200,
entertainment: 150
};
// Sum all values
const total = Object.values(monthlyExpenses).reduce((sum, cost) => sum + cost, 0);
console.log(`Total: $${total}`); // "Total: $2370"
// Find highest expense
const highest = Math.max(...Object.values(monthlyExpenses));
console.log(`Highest: $${highest}`); // "Highest: $1500"
// Average expense
const avg = total / Object.values(monthlyExpenses).length;
console.log(`Average: $${avg.toFixed(2)}`); // "Average: $474.00"Checking if a Value Exists
const permissions = {
read: true,
write: true,
delete: false,
admin: false
};
const hasAnyEnabled = Object.values(permissions).some(v => v === true);
console.log(hasAnyEnabled); // true
const allEnabled = Object.values(permissions).every(v => v === true);
console.log(allEnabled); // falseObject.entries()
Object.entries() returns an array of [key, value] pairs, which is the most versatile of the three methods:
const user = {
name: "Alice",
age: 28,
role: "developer"
};
const entries = Object.entries(user);
console.log(entries);
// [["name", "Alice"], ["age", 28], ["role", "developer"]]Iterating with Destructuring
Object.entries pairs perfectly with destructuring in loops:
const inventory = {
laptops: 45,
phones: 120,
tablets: 30,
monitors: 65
};
for (const [product, count] of Object.entries(inventory)) {
console.log(`${product}: ${count} units`);
}
// laptops: 45 units
// phones: 120 units
// tablets: 30 units
// monitors: 65 unitsFiltering Object Properties
const scores = {
Alice: 92,
Bob: 65,
Charlie: 88,
Diana: 45,
Eve: 97
};
// Keep only passing scores (>= 70)
const passing = Object.fromEntries(
Object.entries(scores).filter(([name, score]) => score >= 70)
);
console.log(passing);
// { Alice: 92, Charlie: 88, Eve: 97 }Transforming Object Data
const prices = {
apple: 1.50,
banana: 0.75,
orange: 2.00,
mango: 3.50
};
// Apply 20% discount to all prices
const discounted = Object.fromEntries(
Object.entries(prices).map(([fruit, price]) => [fruit, +(price * 0.8).toFixed(2)])
);
console.log(discounted);
// { apple: 1.2, banana: 0.6, orange: 1.6, mango: 2.8 }Comparison of All Three Methods
| Method | Returns | Best For |
|---|---|---|
Object.keys(obj) | string[] | Counting properties, checking existence, key-based iteration |
Object.values(obj) | any[] | Calculations, aggregations, value-based checks |
Object.entries(obj) | [string, any][] | Full iteration, transformation, filtering, conversion |
const product = {
name: "Laptop",
price: 999,
inStock: true
};
console.log(Object.keys(product)); // ["name", "price", "inStock"]
console.log(Object.values(product)); // ["Laptop", 999, true]
console.log(Object.entries(product)); // [["name", "Laptop"], ["price", 999], ["inStock", true]]Object.fromEntries()
Object.fromEntries() is the reverse of Object.entries(). It converts an array of [key, value] pairs back into an object:
const entries = [
["name", "Alice"],
["age", 28],
["role", "developer"]
];
const user = Object.fromEntries(entries);
console.log(user);
// { name: "Alice", age: 28, role: "developer" }Converting Map to Object
const userMap = new Map([
["name", "Alice"],
["age", 28],
["email", "alice@example.com"]
]);
const userObj = Object.fromEntries(userMap);
console.log(userObj);
// { name: "Alice", age: 28, email: "alice@example.com" }entries + fromEntries Pipeline
The entries → transform → fromEntries pipeline is the standard pattern for transforming objects:
const rawData = {
" Name ": " Alice ",
" Email": " alice@example.com ",
"Role ": " developer "
};
// Clean up all keys and values
const cleaned = Object.fromEntries(
Object.entries(rawData).map(([key, value]) => [
key.trim().toLowerCase(),
typeof value === "string" ? value.trim() : value
])
);
console.log(cleaned);
// { name: "Alice", email: "alice@example.com", role: "developer" }Practical Patterns
Grouping Array Items into an Object
const orders = [
{ id: 1, category: "electronics", total: 299 },
{ id: 2, category: "clothing", total: 49 },
{ id: 3, category: "electronics", total: 599 },
{ id: 4, category: "food", total: 25 },
{ id: 5, category: "clothing", total: 89 }
];
const grouped = orders.reduce((acc, order) => {
const key = order.category;
if (!acc[key]) acc[key] = [];
acc[key].push(order);
return acc;
}, {});
// Summary per category
const summary = Object.fromEntries(
Object.entries(grouped).map(([category, items]) => [
category,
{
count: items.length,
total: items.reduce((sum, o) => sum + o.total, 0)
}
])
);
console.log(summary);
// { electronics: { count: 2, total: 898 }, clothing: { count: 2, total: 138 }, food: { count: 1, total: 25 } }Inverting an Object (Swap Keys and Values)
const statusCodes = {
200: "OK",
404: "Not Found",
500: "Internal Server Error",
403: "Forbidden"
};
const statusNames = Object.fromEntries(
Object.entries(statusCodes).map(([code, name]) => [name, Number(code)])
);
console.log(statusNames);
// { OK: 200, "Not Found": 404, "Internal Server Error": 500, Forbidden: 403 }Picking Specific Properties
function pick(obj, keys) {
return Object.fromEntries(
Object.entries(obj).filter(([key]) => keys.includes(key))
);
}
function omit(obj, keys) {
return Object.fromEntries(
Object.entries(obj).filter(([key]) => !keys.includes(key))
);
}
const user = {
id: 42,
name: "Alice",
email: "alice@example.com",
password: "secret",
role: "admin"
};
console.log(pick(user, ["name", "email"]));
// { name: "Alice", email: "alice@example.com" }
console.log(omit(user, ["password", "role"]));
// { id: 42, name: "Alice", email: "alice@example.com" }Sorting an Object by Values
const scores = {
Alice: 92,
Bob: 65,
Charlie: 88,
Diana: 97,
Eve: 78
};
const sorted = Object.fromEntries(
Object.entries(scores).sort(([, a], [, b]) => b - a)
);
console.log(sorted);
// { Diana: 97, Alice: 92, Charlie: 88, Eve: 78, Bob: 65 }Property Order
Objects in JavaScript maintain insertion order for string keys (with numeric-like keys sorted first):
const mixed = { b: 2, a: 1, "2": "two", "1": "one", c: 3 };
console.log(Object.keys(mixed));
// ["1", "2", "b", "a", "c"]
// Numeric keys come first (sorted), then string keys in insertion orderBest Practices
- Use
Object.entriesas your default when you need both keys and values - Combine with array methods:
entries → map/filter/reduce → fromEntriesis the standard transformation pipeline - Prefer
Object.keys().lengthoverfor...inloops for counting properties - Use destructuring in
entriescallbacks:([key, value]) =>instead of(entry) => entry[0] - Use
Object.fromEntries()to convert transformed entries back to objects cleanly
Common Mistakes to Avoid
Modifying Objects During Iteration
const data = { a: 1, b: 2, c: 3 };
// WRONG: modifying while iterating (unpredictable)
for (const key of Object.keys(data)) {
if (data[key] < 2) delete data[key]; // Risky!
}
// CORRECT: create a new object with filter
const filtered = Object.fromEntries(
Object.entries(data).filter(([, value]) => value >= 2)
);
console.log(filtered); // { b: 2, c: 3 }Forgetting Object.keys Returns Strings
const data = { 1: "one", 2: "two", 3: "three" };
Object.keys(data).forEach(key => {
console.log(typeof key); // "string" (not number!)
console.log(key === 1); // false (string !== number)
console.log(key === "1"); // true
});Rune AI
Key Insights
- Object.keys(): Returns an array of property names; ideal for counting, existence checks, and key iteration
- Object.values(): Returns an array of property values; perfect for calculations and aggregations
- Object.entries(): Returns
[key, value]pairs; the most versatile for full transformation pipelines - Object.fromEntries(): Converts entries back to objects, completing the
entries → transform → fromEntriesworkflow - Own enumerable only: All three methods skip inherited and non-enumerable properties, making them safer than
for...in
Frequently Asked Questions
Do these methods include inherited properties?
Do they include Symbol properties?
What is the difference between Object.keys and for...in?
Can I use these on arrays?
Is the property order guaranteed?
Conclusion
Object.keys(), Object.values(), and Object.entries() bridge the gap between objects and arrays in JavaScript. They convert object data into arrays that you can iterate, transform, filter, and reduce using the full power of array methods. Combined with Object.fromEntries(), they form a complete pipeline for object data transformation. Mastering these four methods unlocks clean, functional patterns for working with any object-shaped data in your applications.
More in this topic
OffscreenCanvas API in JS for UI Performance
Master the OffscreenCanvas API to offload rendering from the main thread. Covers worker-based 2D and WebGL rendering, animation loops inside workers, bitmap transfer, double buffering, chart rendering pipelines, image processing, and performance measurement strategies.
Advanced Web Workers for High Performance JS
Master Web Workers for truly parallel JavaScript execution. Covers dedicated and shared workers, structured cloning, transferable objects, SharedArrayBuffer with Atomics, worker pools, task scheduling, Comlink RPC patterns, module workers, and performance profiling strategies.
JavaScript Macros and Abstract Code Generation
Master JavaScript code generation techniques for compile-time and runtime metaprogramming. Covers AST manipulation, Babel plugin authorship, tagged template literals as macros, code generation pipelines, source-to-source transformation, compile-time evaluation, and safe eval alternatives.