All topics
Objectsintermediate

Map and Set vs Plain Objects and Arrays

The dedicated key-value and unique-value collection types, and why they're often better choices than objects and arrays for certain use cases.

Map and Set were added in ES6 as dedicated collection types alongside the plain object and array that JavaScript already had, and they solve specific limitations that plain objects and arrays have when used as general-purpose key-value stores or unique-value collections. Interviewers ask about them to check whether you reach for the right built-in data structure rather than reflexively using an object for everything.

A plain object used as a map is like using sticky notes labeled with only single words stuck to a corkboard that came with some notes already pre-stuck on it (inherited prototype properties) — a Map is a purpose-built filing cabinet with labeled drawers that accepts any kind of label, including photographs (objects) as labels, and comes completely empty to start.

Key Concepts

1
A Map is a key-value collection, like an object, but with several concrete advantages: any value — including objects, functions, or NaN — can be used as a key, not just strings and symbols as with plain objects (where non-string/symbol keys get silently coerced to strings). A Map also maintains insertion order reliably during iteration, has a .size property (versus manually counting Object.keys(obj).length), is directly iterable with for...of, and doesn't have the collision risk of accidentally overwriting inherited properties from Object.prototype (like toString or constructor) the way a plain object used as a map can.
MapNaN.sizeObject.keys(obj).lengthfor...of
2
A Set is a collection of unique values — attempting to add a duplicate value is a no-op, since Set uses same-value-zero equality internally to check for existing entries. This makes deduplicating an array trivially easy ([...new Set(array)]) and gives you efficient membership testing (set.has(value) is average O(1), versus array.includes(value)'s O(n) linear scan) when you don't need indexed access or duplicate values.
Set[...new Set(array)]set.has(value)array.includes(value)
3
The tradeoffs: Map and Set don't have a literal syntax (no {}-style shorthand) and aren't directly JSON-serializable with JSON.stringify (they serialize to {} by default, requiring manual conversion via Object.fromEntries/spread first), so plain objects and arrays remain more convenient for simple, JSON-friendly data structures, static configuration, or React-style renderable state. The right choice depends on whether you need Map/Set's specific advantages (non-string keys, guaranteed order, frequent add/remove/lookup, easy deduplication) or just need straightforward serializable data.
MapSet{}JSON.stringifyObject.fromEntries