Skip to content
Laviyx Learn

Try

JavaScript course menu

JavaScript Map and Set: When to Use Them Instead of Objects and Arrays

Learn JavaScript Map and Set: creating Maps, get, set, has and delete, any type of key, iteration order and size, Map vs object; Sets for unique values, removing duplicates, set operations, and WeakMap and WeakSet.

Beginner8 min readUpdated
On this page

Objects and arrays cover most needs, but two built-in collections are better for specific jobs: Map for key-value data that changes often or needs non-string keys, and Set for collections of unique values.

Map#

A Map stores key-value pairs, like an object, with a clearer API:

JavaScript
const stock = new Map();

stock.set("pens", 40);
stock.set("notebooks", 12);
stock.set("pens", 35);          // updates the existing key

console.log(stock.get("pens"));
console.log(stock.has("erasers"));
console.log(stock.size);

stock.delete("notebooks");
console.log(stock);
Output
35
false
2
Map(1) { 'pens' => 35 }
Method or propertyDoes
map.set(key, value)Adds or updates (and returns the map, so calls can be chained)
map.get(key)Reads a value (undefined if missing)
map.has(key)Checks a key
map.delete(key)Removes a key
map.sizeNumber of entries
map.clear()Removes everything

Creating from pairs and looping#

JavaScript
const prices = new Map([
  ["tea", 20],
  ["coffee", 35],
]);

for (const [drink, price] of prices) {
  console.log(`${drink}: ₹${price}`);
}
console.log([...prices.keys()]);
console.log(Object.fromEntries(prices));
Output
tea: ₹20
coffee: ₹35
[ 'tea', 'coffee' ]
{ tea: 20, coffee: 35 }

Maps remember insertion order, and are iterable, so for...of works directly.

Any type of key#

Object keys are always strings (or symbols). Map keys can be anything, including objects:

JavaScript
const asha = { name: "Asha" };
const ravi = { name: "Ravi" };

const lastSeen = new Map();
lastSeen.set(asha, "10:30");
lastSeen.set(ravi, "11:05");

console.log(lastSeen.get(asha));

const obj = {};
obj[asha] = "10:30";
console.log(Object.keys(obj));
Output
10:30
[ '[object Object]' ]

Using an object as a key in a plain object turns it into the string "[object Object]", so every object would collide. A Map keeps them separate.

Map or object?#

Use a Map whenUse an object when
Keys are added and removed oftenThe shape is fixed (a user, a config)
Keys are not stringsYou need JSON (Maps do not convert to JSON directly)
You need the size quickly, or guaranteed orderYou need methods and this
Counting or cachingDestructuring and spread are convenient

Counting with a Map:

JavaScript
const words = "the cat and the hat and the bat".split(" ");
const counts = new Map();
for (const w of words) {
  counts.set(w, (counts.get(w) ?? 0) + 1);
}
console.log(counts);
Output
Map(5) { 'the' => 3, 'cat' => 1, 'and' => 2, 'hat' => 1, 'bat' => 1 }

Set#

A Set holds unique values: adding something it already contains does nothing:

JavaScript
const tags = new Set();
tags.add("html");
tags.add("css");
tags.add("html");

console.log(tags);
console.log(tags.size);
console.log(tags.has("css"));
tags.delete("css");
console.log([...tags]);
Output
Set(2) { 'html', 'css' }
2
true
[ 'html' ]

Removing duplicates#

The most common use of a Set:

JavaScript
const visits = ["home", "about", "home", "blog", "about", "home"];
const unique = [...new Set(visits)];
console.log(unique);
Output
[ 'home', 'about', 'blog' ]

has on a Set is much faster than includes on a large array, so Sets are also good for "have I seen this before?" checks.

Set operations#

JavaScript
const frontend = new Set(["html", "css", "javascript"]);
const backend = new Set(["javascript", "sql", "python"]);

const both = [...frontend].filter((x) => backend.has(x));
const all = new Set([...frontend, ...backend]);
const onlyFrontend = [...frontend].filter((x) => !backend.has(x));

console.log(both);
console.log(all.size);
console.log(onlyFrontend);
Output
[ 'javascript' ]
5
[ 'html', 'css' ]

Newer versions of JavaScript (ES2025) also add built-in methods such as a.intersection(b), a.union(b) and a.difference(b), available in current browsers and Node.js 22 and later.

WeakMap and WeakSet#

WeakMap and WeakSet hold objects without preventing them from being garbage-collected. They are used for advanced cases such as attaching private data or caches to objects you do not own, so that the data disappears automatically when the object does. They cannot be iterated or counted.

Practice#

Practice exercise

Given const emails = ["a@x.com", "b@x.com", "A@x.com", "c@x.com", "b@x.com"], print the number of unique emails, ignoring case. Then use a Map to count how many emails each domain has in ["a@x.com", "b@y.com", "c@x.com"].

Show solution
JavaScript
const emails = ["a@x.com", "b@x.com", "A@x.com", "c@x.com", "b@x.com"];
const unique = new Set(emails.map((e) => e.toLowerCase()));
console.log(unique.size);

const domains = new Map();
for (const email of ["a@x.com", "b@y.com", "c@x.com"]) {
  const domain = email.split("@")[1];
  domains.set(domain, (domains.get(domain) ?? 0) + 1);
}
console.log(domains);
Output
3
Map(2) { 'x.com' => 2, 'y.com' => 1 }

Key takeaway#

Finished this lesson?