Map.prototype.keys()

Returns an iterator over the map's keys in insertion order.

Signature
keys()
  • Added in JavaScript ES2015

Return value

Map IteratorA new iterable iterator object yielding each key in the map, in insertion order.

Errors

Throws a TypeError when called on a value that is not a real Map.

Changelog

  • PHP ES2015Introduced with the Map built-in.
  • PHP ES2025Iterator helper methods such as map(), filter() and take() became available on the returned iterator via Iterator.prototype.

keys() gives you an iterator, not an array. That trips people up immediately: there is no .length, no .map() in older engines, and no index access. Spread it or wrap it — [...map.keys()] or Array.from(map.keys()) — whenever you want array methods such as sort() or join().

It is live and single-use

The iterator reads the map as it goes rather than snapshotting it. Entries added after you created the iterator but before it finishes are still yielded; entries deleted in the meantime are skipped. It is also exhausted once consumed — a second spread of the same iterator variable produces an empty array, which is why you usually call map.keys() fresh each time rather than storing it.

When to reach for it

Use keys() when you only care about which keys exist: comparing two maps, building a sorted index, or feeding the key list to something else. If you need both halves, iterate the map directly — for (const [k, v] of map) — rather than looking each value up by key.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Collect the map's keys into a sorted array for display
  • Compare which keys two maps have in common
  • Take the oldest key from an insertion-ordered cache
  • Feed the key list to Set operations or a join()

Frequently asked questions

How do I turn Map keys into an array?

Spread or convert the iterator: [...map.keys()] or Array.from(map.keys()). keys() itself returns an iterator, which has no length and no array methods.

Are Map keys returned in a guaranteed order?

Yes, always in insertion order. Overwriting an existing key does not change its position; deleting and re-adding it moves it to the end.

Why is my Map keys iterator empty the second time?

An iterator is consumed once. After you spread or loop over it, it is exhausted — call map.keys() again for a fresh one.

More examples

Comparing the keys of two maps

Putting one map's keys in a Set makes the membership test constant time. The last line spreads both key iterators into a Set to get the union without duplicates, in first-seen order.

Example · javascript
const a = new Map([["x", 1], ["y", 2]]);
const b = new Map([["y", 9], ["z", 8]]);

const bKeys = new Set(b.keys());
const shared = [...a.keys()].filter((k) => bKeys.has(k));
const onlyInA = [...a.keys()].filter((k) => !bKeys.has(k));

console.log(shared);
console.log(onlyInA);
console.log([...new Set([...a.keys(), ...b.keys()])]);

The iterator follows later changes

Because the iterator walks the live map, "b" never appears and "c" does. Snapshot with [...map.keys()] first if you intend to mutate the map while looping.

Example · javascript
const m = new Map([["a", 1], ["b", 2]]);
const it = m.keys();

console.log(it.next().value); // "a"
m.delete("b");                // not reached yet — skipped
m.set("c", 3);                // added at the end — will be yielded

console.log([...it]);         // ["c"]
console.log([...m.keys()]);   // ["a", "c"]

Discussion

  • Be the first to comment on this lesson.