JavaScript Map

Why should you care about 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.

JavaScript Map diagram showing key-value pairs with different key types (string, number, boolean, object)

javascript

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

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.

javascript

// 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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.

javascript

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.

It returns false if the key did not exist.

javascript

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.

There is a catch.

Map matches keys by identity, not by content.

Think of house keys. Two keys can look identical, but only the exact key opens that door.

javascript

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.

So map.get([10, 20]) returns undefined, even when the values look identical.

You can iterate over a Map with a for...of loop.

Use map.entries(), map.keys(), or map.values().

Map entries are returned in insertion order.

javascript

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).

Object.entries(obj) returns an array of [key, value] pairs.

You can pass that array directly to new Map().

javascript

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 produce an array of [key, value] pairs.

javascript

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. This is the opposite of what you might expect from a key-value pair.

javascript

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 similar to a Map, but with a looser grip on its keys.

It only allows objects as keys. Strings and numbers are not allowed.

It holds those keys weakly.

If nothing else references the key object, JavaScript can clean it up from memory.

Because of this, you cannot loop over a WeakMap.

You also cannot check its size.

Methods like keys(), values(), and clear() are not available.

WeakMap is useful when you attach extra data to an object.

It does this without preventing JavaScript from cleaning that object up later.

javascript

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, the entry can 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 undefined if not found.
  • has(key) - returns true if the key exists, otherwise false.
  • 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...of with entries(), keys(), or values().
  • Object to Map - use new Map(Object.entries(obj)).
  • Map to Array - use [...map] or Array.from(map).
  • forEach - callback receives (value, key) - value comes first.
  • WeakMap - like Map but keys must be objects and are weakly held (garbage collectible).

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.