Skip to main content

The Map collection in JavaScript

Map is a built in JavaScript object that stores key, value pairs and remembers the insertion order of those pairs. It looks like a plain object {}, but it has extra abilities: a key may be any data type, it comes with convenient methods for adding, removing and iterating, and the order of elements is guaranteed.

Theory

TL;DR

  • Map is a collection of key, value pairs with a guaranteed insertion order.
  • A key can be anything: a string, a number, an object, a function, even NaN.
  • Object keys are compared by reference, not by their string representation.
  • Methods: set, get, has, delete, clear, plus the size property.
  • The collection is iterable: for...of, .forEach(), .keys(), .values(), .entries().
  • Conversion works both ways: new Map(Object.entries(obj)) and Object.fromEntries(map).

Quick example

javascript
const map = new Map(); map.set('name', 'Alex'); map.set('age', 25); console.log(map.get('name')); // Alex console.log(map.get('age')); // 25 console.log(map.size); // 2

Core methods and properties

Method / propertyWhat it doesExample
set(key, value)Adds an entrymap.set('a', 1)
get(key)Returns the value for a keymap.get('a')
has(key)Checks whether a key existsmap.has('a') // true
delete(key)Removes an entrymap.delete('a')
clear()Empties the whole collectionmap.clear()
sizeNumber of entriesmap.size // 2

set() returns the Map itself, so calls can be chained: map.set('a', 1).set('b', 2).

Keys of any type

javascript
const map = new Map(); const objKey = { id: 1 }; const funcKey = () => {}; const numKey = 42; map.set(objKey, 'object'); map.set(funcKey, 'function'); map.set(numKey, 'number'); console.log(map.get(objKey)); // object console.log(map.get(funcKey)); // function console.log(map.get(42)); // number

Unlike a plain object {}, keys here are compared by reference, not by their stringified form. So { id: 1 } and a fresh literal { id: 1 } are two different keys.

Even NaN works as a key, which is impossible in plain objects:

javascript
const map = new Map(); map.set(NaN, 'Not a Number'); console.log(map.get(NaN)); // 'Not a Number'

Iterating a Map

Map is an iterable collection, so you can walk it in several ways.

  1. for...of:
javascript
const map = new Map([ ['name', 'Alex'], ['age', 25], ]); for (const [key, value] of map) { console.log(`${key}: ${value}`); } // name: Alex // age: 25
  1. The forEach method (mind the argument order: value first, key second):
javascript
map.forEach((value, key) => { console.log(key, value); });
  1. Keys, values or entries separately:
javascript
console.log([...map.keys()]); // ['name', 'age'] console.log([...map.values()]); // ['Alex', 25] console.log([...map.entries()]); // [['name','Alex'], ['age',25]]

Map versus a plain object

FeatureObjectMap
Key typeString or symbol onlyAny type, including objects and functions
Order of elementsNot guaranteed (before ES2015)Guaranteed
Number of entriesCounted manually (Object.keys().length)map.size
Removaldelete obj.key (slow)map.delete(key) (fast)
Iterationfor...in (picks up inherited properties)Clean for...of
PerformanceBetter for small data setsBetter for frequent inserts and deletes

Conversion and practical use

From an object to a Map:

javascript
const obj = { a: 1, b: 2 }; const map = new Map(Object.entries(obj));

From a Map to an object:

javascript
const obj2 = Object.fromEntries(map);

An occurrence counter, the classic case for a Map:

javascript
const arr = ['a', 'b', 'a', 'c', 'b', 'a']; const counter = new Map(); for (const item of arr) { counter.set(item, (counter.get(item) || 0) + 1); } console.log(counter); // Map(3) { 'a' => 3, 'b' => 2, 'c' => 1 }

Reach for Map when:

  • you need keys that are not only strings;
  • insertion order matters;
  • entries are added and removed often;
  • you are working with associative data structures.

Short summary:

WhatDescription
TypeA key, value collection
KeysAny type, including objects
OrderPreserved
Methods.set(), .get(), .has(), .delete(), .clear()
Sizemap.size
Iterationfor...of, .forEach(), .keys(), .values(), .entries()

Common mistakes

  • Treating a Map like an object. map['name'] creates a regular property on the Map object rather than an entry in the collection, and map.get('name') will return undefined.
  • Expecting map.length. A Map has no length, it has size, and that is a property, not a method.
  • Using a fresh object literal as a lookup key. map.set({ id: 1 }, x) and map.get({ id: 1 }) are different references, so the result is undefined.
  • Mixing up the forEach argument order. The callback receives (value, key, map), not (key, value).
  • Serialising a Map with JSON.stringify. The result is {}; convert the collection into an object or an array first, for example with Object.fromEntries(map).
  • Keeping object keys in a Map and expecting garbage collection. A Map holds strong references; for weak ones you need a WeakMap.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.