ES6 introduced Map and Set as specialized alternatives to plain objects and arrays — Map allows any key type with guaranteed order, while Set stores unique values with O(1) lookups.
Map allows any key type, guarantees insertion order, has O(1) .size, and avoids prototype pollution — use for dynamic or non-string keys
Set stores unique values with O(1) .has() lookups — use for uniqueness checks; Array for ordered, indexed, duplicate-allowed lists
Hold weak references to object keys — values are garbage collected when keys lose all other references; prevents memory leaks
Set.has() is O(1) vs Array.includes() O(n); Map add/delete is optimized vs Object delete which can deoptimize V8 hidden classes
Object.entries() → Map, Object.fromEntries() → Object, [...new Set(arr)] for deduplication, Array.from(set) for Set → Array
JavaScript has four primary built-in collection types: Object and Array (since the beginning) and Map and Set (added in ES6). Each is optimized for different use cases, and choosing the right one matters for performance and code clarity.
Map accepts any value as a key — objects, functions, numbers, even NaN. Object keys are always coerced to strings (or symbols).Map guarantees insertion order when iterating. Object property order is mostly insertion-ordered for string keys, but numeric keys are sorted first.Map has a .size property for O(1) count. Objects require Object.keys(obj).length, which is O(n).Map is optimized for frequent additions and deletions. Object property deletion with delete can deoptimize the object's hidden class in V8.constructor, toString, or __proto__ can collide with inherited properties. Map has no such issue.Object for structured data with known string keys (configs, user profiles, API responses). Use Map when keys are dynamic, non-string, or frequently added/removed.Set stores only unique values — adding a duplicate is silently ignored. Arrays allow duplicates.Set.has(value) is O(1) average. Array.includes(value) is O(n) — for large collections, Set is dramatically faster for existence checks.Set has no index-based access. You cannot do set[0] like array[0]. If you need ordered, indexed access, use an Array.[...new Set(array)].Array for ordered lists where you need index access, .map(), .filter(), .reduce(), or duplicates. Use Set when uniqueness matters or you need fast .has() lookups.WeakMap and WeakSet hold weak references to their keys/values — if the key object has no other references, it can be garbage collected. This prevents memory leaks.WeakMap keys must be objects (not primitives). You cannot iterate over a WeakMap or check its size.new Map(Object.entries(obj))Object.fromEntries(map)new Set(array)[...set] or Array.from(set)Key Interview Distinction: When to Choose Each Ordered list with duplicates → Array. Unique values with fast lookups → Set. Structured data with known string keys → Object. Dynamic keys of any type with frequent add/delete → Map. This decision framework is commonly tested in interviews.
Fun Fact
Map and Set were added in ES6 (2015), but JavaScript had no built-in hash map for 20 years before that. Developers used plain objects as maps, which led to bizarre bugs — for example, obj['toString'] would return the inherited method instead of undefined, and '__proto__' as a key could break the entire object.