Object.entries()

The one to reach for when transforming an object. Paired with Object.fromEntries it gives objects the map and filter they never had.

Object static methodES2017Live demo
Common call
Object.entries(obj)
Returns
an array of [key, value] pairs
Replaces
for...in with manual pair building
Watch out
the pairs are arrays, so destructure them in the callback
Object.entries(objectobject — Any object. Primitives are coerced; null and undefined throw TypeError.type: object · required)
→ [string, any][]

Demo

Live evaluation
Try:
Inputs
jsonstringa JSON object, e.g. {"a":1}
Output
Object.entries(JSON.parse('{"a":1,"b":2}'))
[['a', 1], ['b', 2]]

Each pair is a two-element array, which is what makes the map-filter-fromEntries pipeline possible — and why callbacks over entries almost always destructure with ([key, value]). The same integer-key reordering applies as with keys and values, but here it does no harm: each key travels with its own value, so nothing can be misaligned. An array yields index-value pairs, with the indices as strings.

Parameters

NameTypeRequiredDescription
objectobjectyesAny object. Primitives are coerced; null and undefined throw TypeError.

Return value

[string, any][] — An array of [key, value] pairs for the own enumerable properties, in Object.keys order. Each pair is a two-element array.

Common patterns

Transform an object
The canonical entries-map-fromEntries round trip.
const upper = Object.fromEntries(
  Object.entries(obj).map(([k, v]) => [k, String(v).toUpperCase()])
);
Filter properties out
Objects have no filter of their own.
const clean = Object.fromEntries(
  Object.entries(obj).filter(([, v]) => v != null)
);
Iterate with both parts
Destructure in the for...of head.
for (const [key, value] of Object.entries(obj)) { }

Examples

1. Pairs
Object.entries({a: 1, b: 2})
Returns
[['a', 1], ['b', 2]]
2. Key order applies
Object.entries({b: 2, 1: 1})
Returns
[['1', 1], ['b', 2]]
3. An array
Object.entries([10, 20])
Returns
[['0', 10], ['1', 20]]
4. Round trip
Object.fromEntries(Object.entries({a: 1}))
Returns
{a: 1}
5. Straight to a Map
new Map(Object.entries({a: 1}))
Returns
Map(1) {'a' => 1}
6. null throws
Object.entries(null)
Returns
TypeError: Cannot convert undefined or null to object

Pitfalls

1. Forgetting to destructure the pair
Each element is an ARRAY, not a key. A callback written as (k, v) receives the whole pair as k and the index as v, which produces baffling output rather than an error.
Pair as first arg
Object.entries({a: 1}).map((k, v) => k)
[['a', 1]] // k is the pair
Destructure
Object.entries({a: 1}).map(([k, v]) => k)
['a']
2. Keys are always strings, even from arrays
Round-tripping an array through entries and fromEntries gives you an OBJECT with string keys, not an array. The structure changes shape silently.
Now an object
Object.fromEntries(Object.entries([10, 20]))
{'0': 10, '1': 20}
Keep it an array
[10, 20].map(x => x)
[10, 20]
3. It allocates an array per property
Every pair is a fresh two-element array on top of the outer array. For a handful of properties that is irrelevant; inside a hot loop over large objects, a plain for...of over Object.keys allocates far less.
n + 1 arrays
for (const [k, v] of Object.entries(huge)) { }
allocates per property
Keys only
for (const k of Object.keys(huge)) { const v = huge[k]; }
one array
4. Only own enumerable properties, as ever
Inherited, non-enumerable and symbol-keyed properties are all absent — so an entries round trip quietly drops them. Converting a class instance this way loses everything on its prototype, including its methods.
Methods lost
Object.fromEntries(Object.entries(instance))
a plain object, no prototype
Copy with the prototype
Object.assign(Object.create(Object.getPrototypeOf(i)), i)
prototype kept

When to use

Use it
  • Mapping or filtering an object property by property
  • Iterating where you need both the key and the value
  • Converting an object to a Map
  • Sorting properties before rebuilding an object
Reach for something else
  • You only need one side → Object.keys or Object.values
  • Very large objects in a hot path → iterate keys and index in
  • The source is an array → array methods directly
  • You need inherited properties → getOwnPropertyDescriptors, or walk the chain

Notes

Complexity
O(n) in the number of own enumerable properties
Return
A new array of new two-element arrays; values are references
CPython impl
V8: Builtins-object-entries
Memory
Allocates one array per property plus the outer array
Thread-safe
Single-threaded; the object is only read

FAQ

There is no Object.map. The idiom is entries, then the array method you want, then fromEntries to rebuild. Destructure the pair in the callback and return a new pair.

Object.fromEntries(
  Object.entries(obj).map(([k, v]) => [k, v * 2])
);

History

ES2017
Object.entries added alongside Object.values.
ES2019
Object.fromEntries added, making the round trip practical.