JavaScript Map and Set
In this chapter, you will learn about Map and Set in JavaScript. These data structures can add extra capabilities to JavaScript to simplify common tasks.
This chapter covers two keyed collections introduced in modern JavaScript: Map (key-value pairs) and Set (unique values). You will learn what they do, when to reach for them instead of plain objects and arrays, how to iterate them, and the patterns you will actually use day to day, such as deduplicating an array or building a frequency counter.
JavaScript Map
A Map is a collection of key-value pairs, much like a plain object — but with important differences that make it the better choice in many situations.
Map vs. plain object: when to use a Map
Reach for a Map over a plain object when:
- Keys are not strings. Object keys are always coerced to strings (or symbols). A Map lets you use any value as a key: objects, functions, numbers, even
NaN. - You add and remove entries often. Maps are optimized for frequent insertion and deletion, and
map.sizegives the count directly (objects needObject.keys(obj).length). - You need guaranteed iteration order. A Map always iterates in insertion order.
- You want to avoid prototype collisions. A plain object inherits keys like
toStringandconstructor; a Map has no such built-in keys, so user-supplied keys can never clash with them.
Use a plain object when the data is a fixed, known shape (a record), or when you need JSON serialization — JSON.stringify works on objects but not on Maps.
Creating and manipulating Maps
To create a Map, use new Map(). It supports these methods and properties:
map.set(key, value): Adds or updates a key-value pair. Returns the Map, so calls can be chained.map.get(key): Retrieves the value for a key (undefinedif absent).map.has(key): Returnstrueif the key exists.map.delete(key): Removes a key-value pair.map.clear(): Removes everything.map.size: The number of key-value pairs.
Because set() returns the Map, you can chain calls:
Using any value as a key
Unlike objects, a Map keeps keys as-is. The number 1 and the string "1" are different keys, and objects or functions can be keys (compared by reference):
Iterating over a Map
A Map iterates in insertion order and offers three iterator methods plus forEach:
map.keys()— an iterable of keys.map.values()— an iterable of values.map.entries()— an iterable of[key, value]pairs (this is the default, sofor...of mapworks directly).map.forEach((value, key) => ...)— runs a callback for each entry.
Converting between Map and object
A Map can be built from an object's entries and turned back into one:
JavaScript Set
A Set is a collection of unique values — each value can appear only once. It is closely related to an array, but with no duplicates and no index access.
Set vs. array: when to use a Set
Reach for a Set over an array when:
- Uniqueness matters. A Set automatically rejects duplicates, so you never need to check before adding.
- You test membership often.
set.has(value)is fast and reads cleanly, whereasarray.includes(value)scans the whole array each time.
Stick with an array when order-by-index, duplicates, or array methods like map/filter/reduce are what you need. (You can always convert between the two.)
Working with Sets
new Set(iterable): Creates a Set, optionally from an array or any iterable.set.add(value): Adds a value (returns the Set, so calls chain). Duplicates are ignored.set.has(value): Returnstrueif the value is present.set.delete(value): Removes a value.set.size: The number of values.set.clear(): Removes everything.
Deduplicating an array (the #1 use)
The most common reason to use a Set is to remove duplicates from an array. Spread the Set back into an array with [...new Set(arr)]:
Iterating over a Set
Sets iterate in insertion order and support for...of and forEach:
Union, intersection, and difference
Sets make classic set operations easy. Modern engines also provide built-in set.union(), set.intersection(), and set.difference() methods, but here is the portable approach using arrays:
A real scenario: word-frequency counter
This example shows why a Map often beats a plain object. We count how many times each word appears in a sentence. With a Map, keys stay as real string values, size is immediate, and there is no risk of a word colliding with an inherited property name:
Both Map and Set are iterables, so they work with for...of, the spread operator (...), and destructuring. In addition, JavaScript provides WeakMap and WeakSet, which allow their keys to be garbage-collected. Learn more on our JavaScript WeakMap and WeakSet page.
Method cheat-sheet
Map
| Operation | Code |
|---|---|
| Create | new Map() or new Map(Object.entries(obj)) |
| Add / update | map.set(key, value) (chainable) |
| Read | map.get(key) |
| Check | map.has(key) |
| Remove | map.delete(key) |
| Count | map.size |
| Iterate | for (let [k, v] of map), map.keys(), map.values(), map.entries(), map.forEach() |
| To object | Object.fromEntries(map) |
Set
| Operation | Code |
|---|---|
| Create | new Set() or new Set(array) |
| Add | set.add(value) (chainable, ignores duplicates) |
| Check | set.has(value) |
| Remove | set.delete(value) |
| Count | set.size |
| Iterate | for (let v of set), set.forEach() |
| Dedupe array | [...new Set(array)] |
Rule of thumb: use a Map when you need keyed data with non-string keys, frequent updates, or guaranteed order; use a Set when you need a collection of unique values with fast membership checks. For everything else, plain objects and arrays remain the right tools.