Object.keys, Object.values, and Object.entries
These three methods turn an object's own properties into arrays you can loop, map, or filter like any other array.
Loading visual…
Definition
`Object.keys(obj)` returns an array of an object's own enumerable string keys. `Object.values(obj)` returns the corresponding values, in the same order as `Object.keys`. `Object.entries(obj)` returns an array of `[key, value]` pairs, one per property, which pairs naturally with destructuring in a loop: `for (const [key, value] of Object.entries(obj))`. All three only look at the object's own properties, not ones inherited through its prototype chain. The order these methods use is not simply insertion order: any key that looks like a non-negative integer (like `"0"` or `"2"`) is listed first, sorted numerically ascending, and only after those do the remaining string keys appear, in the order they were added. Because `Object.entries` produces plain arrays, the full array toolkit (`map`, `filter`, `reduce`) becomes available for working with an object's data, and `Object.fromEntries(pairs)` reverses the process, turning an array of `[key, value]` pairs back into an object.
Examples
const user = { name: "Ada", age: 30, active: true };
Object.keys(user); // ["name", "age", "active"]
Object.values(user); // ["Ada", 30, true]
Object.entries(user); // [["name","Ada"], ["age",30], ["active",true]]keys, values, and entries all walk the same own properties in the same order, just packaged differently.
const prices = { apple: 2, banana: 1, cherry: 5 };
for (const [name, price] of Object.entries(prices)) {
console.log(`${name}: $${price}`);
}Destructuring each [key, value] pair straight in the for...of header reads cleanly, without indexing into the pair manually.
const doubled = Object.fromEntries(
Object.entries(prices).map(([name, price]) => [name, price * 2]),
);
// { apple: 4, banana: 2, cherry: 10 }entries turns the object into an array of pairs, map transforms each pair, and fromEntries builds a new object back out of the results.
Common mistakes
- Expecting these methods to include inherited properties from the prototype chain; they only see the object's own properties.
- Assuming key order always matches the order properties were written; integer-like keys are always sorted numerically first.
- Trying to for...of directly over an object instead of over Object.entries(obj); a plain object is not iterable by itself.
Key takeaways
- Object.keys, Object.values, and Object.entries all iterate the same own enumerable properties, in the same order as each other.
- Object.entries pairs each key with its value as a two-item array, ready for array methods or destructuring.
- Object.fromEntries reverses Object.entries, turning [key, value] pairs back into an object.
- Integer-like keys are always listed first and sorted numerically, ahead of string keys in insertion order.
const obj = { 2: "b", 1: "a", z: "c" }; Object.keys(obj)
Where you see this
- Rendering a list of form fields or settings by mapping over Object.entries of a config object.
- Converting an object into query-string pairs or a table of rows for display.
- Filtering or transforming an object's properties with Object.entries plus filter/map, then rebuilding it with Object.fromEntries.
- Summing or counting values in a plain object without a for...in loop, using Object.values with reduce.