JavaScript Map
Map gives you reliable key-value storage when plain objects feel limiting. It is especially useful when keys are not just strings, like objects, arrays, or IDs from external data.
A Map is a built-in structure for storing key-value pairs, similar to an object.
The big difference is that Map accepts any type as a key, not just strings. That means numbers, booleans, objects, and arrays can all be keys, and JavaScript keeps each key in its original type instead of converting it to a string.
const map = new Map();
map.set("username", "js_dev"); // string key
map.set(1, "one"); // number key
map.set(true, "yes"); // boolean key
console.log(map.get("username")); // js_dev
console.log(map.get(1)); // one
console.log(map.get(true)); // yes
Both structures store key-value associations, but they express different ownership. Choose Map when the collection itself should keep entries available. Choose WeakMap when metadata should disappear automatically after an object key is no longer used elsewhere.
| Question | Map | WeakMap |
|---|---|---|
| What can be a key? | Any value, including primitives and objects. | Objects and non-registered symbols only. |
| Can you count or iterate entries? | Yes: size and iteration methods. | No enumeration or size; entries may disappear during garbage collection. |
| Does it keep an object key alive? | Yes, while the key remains in the Map. | No. The object can be garbage-collected when nothing else references it. |
| Typical use | Menus, caches, registries, counts, and data you need to list. | Private metadata attached to DOM nodes or objects. |
const visibleUsers = new Map();
visibleUsers.set("user-1", { name: "Sam" });
console.log(visibleUsers.size); // 1: listable application data
const elementMetadata = new WeakMap();
const button = document.querySelector("#save");
elementMetadata.set(button, { clickCount: 0 });
// When the button is removed and no other code references it,
// its WeakMap metadata can be collected automatically.
button.remove();
Do not use WeakMap as a hidden list. You cannot inspect all its entries, force garbage collection, or rely on a specific cleanup moment. If you need to display, count, or save every entry, use a regular Map and remove entries deliberately.
Map. “Is this temporary metadata owned by an object?” Consider WeakMap.
You create a Map with new Map(). You can either start empty and add entries later, or pass an array of [key, value] pairs during creation.
The constructor accepts any iterable that produces two-item pairs, such as an array of arrays or another Map. Each pair becomes one key-value entry, and later entries replace earlier values when they use the same key.
// Empty Map
const emptyMap = new Map();
// Map with initial values
const map = new Map([
["username", "js_dev"],
["role", "admin"],
["status", "active"]
]);
console.log(map); // Map(3) { 'username' => 'js_dev', 'role' => 'admin', 'status' => 'active' }
Use map.set(key, value) to add or update data. If the key already exists, its value is replaced. If the key is new, a new entry is created.
const map = new Map();
map.set("language", "JavaScript");
map.set("version", 2024);
// Update existing key
map.set("language", "TypeScript");
console.log(map.get("language")); // TypeScript
console.log(map.get("version")); // 2024
set() returns the same Map, so you can chain multiple calls in a single statement. This makes initialization shorter and easier to read.
const map = new Map();
map
.set("username", "coder42")
.set("role", "editor")
.set("theme", "dark");
console.log(map.size); // 3
Here's a quick look at the methods and properties you'll use with Map:
set(key, value)- Add or update a key-value pair.get(key)- Retrieve the value for a given key.has(key)- Check whether a key exists in the Map.size- Returns the number of entries in the Map.clear()- Remove all entries from the Map.delete(key)- Remove a specific entry by key.keys()- Returns an iterator of all keys.values()- Returns an iterator of all values.entries()- Returns an iterator of all[key, value]pairs.forEach(callback)- Runs a function for each entry in the Map.
Use map.get(key) to retrieve the value associated with a key. If the key does not exist, it returns undefined.
Because undefined can also be a stored
value, use map.has(key) when you need to
distinguish a missing key from an entry whose value
is explicitly undefined.
const map = new Map([
["role", "admin"],
["theme", "dark"]
]);
console.log(map.get("role")); // admin
console.log(map.get("theme")); // dark
console.log(map.get("locale")); // undefined (key not found)
Use map.has(key) to check whether a key exists in the Map. It returns true if the key is present, and false if not.
const map = new Map([["username", "js_dev"]]);
console.log(map.has("username")); // true
console.log(map.has("locale")); // false
The size property returns the number of key-value pairs stored in the Map.
Unlike arrays, you do not use .length; Maps use .size.
const map = new Map();
map.set("a", 1);
map.set("b", 2);
map.set("c", 3);
console.log(map.size); // 3
The clear() method removes all key-value pairs from the Map.
After calling clear(), the Map still exists. It is just empty.
const map = new Map([["x", 10], ["y", 20]]);
console.log(map.size); // 2
map.clear();
console.log(map.size); // 0
Use map.delete(key) to remove a specific entry.
It returns true if the key was found and removed, and false if the key did not exist.
const map = new Map([["username", "js_dev"], ["role", "admin"]]);
map.delete("role");
console.log(map.has("role")); // false
console.log(map.size); // 1
Since a Map accepts any value as a key, you can even use an array or object as a key. Map object and array keys are matched by reference identity, not by content. Two different arrays or objects with the same contents are different keys.
const coords = [10, 20];
const map = new Map();
map.set(coords, "location A");
console.log(map.get(coords)); // location A
console.log(map.get([10, 20])); // undefined (different array reference)
Two separate arrays with the same values are not the same reference, just as [10, 20] === [10, 20] is false. Map does not compare object and array keys by their contents, so map.get([10, 20]) returns undefined.
You can iterate over a Map with a for...of loop.
Use map.entries(), map.keys(), or map.values(); entries are returned in insertion order.
const map = new Map([["a", 1], ["b", 2], ["c", 3]]);
// Iterate over entries (key-value pairs)
for (const [key, value] of map.entries()) {
console.log(key, value); // a 1, b 2, c 3
}
// Iterate over keys only
for (const key of map.keys()) {
console.log(key); // a, b, c
}
// Iterate over values only
for (const value of map.values()) {
console.log(value); // 1, 2, 3
}
You can convert a plain object to a Map with Object.entries(obj).
This returns an array of [key, value] pairs, which you can pass directly to new Map().
const session = { username: "js_dev", role: "admin", status: "active" };
const map = new Map(Object.entries(session));
console.log(map.get("username")); // js_dev
console.log(map.size); // 3
You can convert a Map to an array with the spread operator [...map].
You can also use Array.from(map); both approaches produce an array of [key, value] pairs.
const map = new Map([["a", 1], ["b", 2]]);
// Using spread operator
const arr1 = [...map];
console.log(arr1); // [['a', 1], ['b', 2]]
// Using Array.from
const arr2 = Array.from(map);
console.log(arr2); // [['a', 1], ['b', 2]]
// Keys or values only as arrays
const keys = [...map.keys()]; // ['a', 'b']
const values = [...map.values()]; // [1, 2]
The forEach method iterates over each entry in the Map.
It calls a callback function with (value, key, map). Notice that value comes before key, which is the opposite of what you might expect from a key-value pair.
const map = new Map([["username", "js_dev"], ["role", "admin"]]);
map.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
// username: js_dev
// role: admin
A WeakMap is an advanced alternative to Map for metadata linked to objects. It only allows objects as keys, holds those keys weakly, and lets JavaScript clean them up when nothing else references the key object.
Because of this, you cannot loop over a WeakMap, check its size, or use methods like keys(), values(), and clear().
The supported operations are set(),
get(), has(), and
delete(). Use them when you know the
object key and do not need to enumerate every entry.
WeakMap is useful when you attach extra data to an object. It does this without preventing JavaScript from cleaning that object up later.
const weakMap = new WeakMap();
let session = { id: "sess_abc123" };
weakMap.set(session, "authenticated");
console.log(weakMap.get(session)); // authenticated
console.log(weakMap.has(session)); // true
// When 'session' is set to null and no other references remain,
// the entry may eventually be garbage collected.
session = null;
- Map - stores key-value pairs where keys can be of any type.
- new Map() - creates a new Map, optionally initialized with
[key, value]pairs. - set(key, value) - adds or updates an entry; returns the Map (chainable).
- get(key) - retrieves the value for a key; returns
undefinedif not found. - has(key) - returns
trueif the key exists, otherwisefalse. - size - returns the number of entries in the Map.
- clear() - removes all entries from the Map.
- delete(key) - removes a specific entry by key.
- Iteration - use
for...ofwithentries(),keys(), orvalues(); Map preserves insertion order. - Object to Map - use
new Map(Object.entries(obj)). - Map to Array - use
[...map]orArray.from(map). - forEach - callback receives
(value, key)- value comes first. - WeakMap - an advanced collection whose object keys are weakly held; it has no enumeration or
size.
What's next? You now know how Maps organize key-value data.
The next tutorial covers destructuring. It makes reading values from objects and arrays much cleaner.
Videos for this topic will be added soon.