Maps in JavaScript

May 29, 2019

A JavaScript Map is an object that stores key/value pairs. You can get() or set() the value associated with a key, or use has() to check whether the map has a given key.

const map = new Map();

map.get('answer'); // undefined
map.has('answer'); // false

map.set('answer', 42);

map.get('answer'); // 42
map.has('answer'); // true

Before ES6, JavaScript objects were often used as maps. Maps have several advantages over objects for storing user data. First, objects have special properties that may collide with key names. If you're not careful, you can end up with a prototype poisoning security vulnerability. That's why you need to be careful whether you use in or hasOwnProperty() if you're using objects as maps.

const obj = {};
const map = new Map();

obj.answer = 42;
map.set('answer', 42);

'answer' in obj; // true
map.has('answer'); // true

'prototype' in obj; // true
map.has('prototype'); // false

'__proto__' in obj; // true
map.has('constructor'); // false

Maps can also store arbitrary keys, whereas objects can only store strings as keys. For example, you can store a JavaScript date key in a map. If you try to store a date as a key in an object, JavaScript will convert the key to a string first.

const map = new Map();

const date = new Date('2019-06-01');

map.set(date, 'test1');
map.set(date.toString(), 'test2');

map.get(date); // 'test1'
map.get(date.toString()); // 'test2'

const obj = {};
obj[date] = 'test1';
obj[date.toString()] = 'test2';
obj[date]; // 'test2', because JavaScript converts object keys to strings

The Map Constructor

The Map constructor takes a single parameter iterable. In practice, iterable is usually an array of key/value pairs [[key1, value1], [key2, value2]]. However, you can also pass a map to the Map constructor.

const date = new Date('2019-06-01');
const map1 = new Map([
  ['answer', 42],
  [date, 'test1']
]);

map1.get('answer'); // 42
map1.get(date); // test1

// If you pass `map1` to the Map constructor, JavaScript will create a
// copy of `map1`
const map2 = new Map(map1);
map2.get('answer'); // 42
map2.get(date); // test1

map2.set('hello', 'world');
map1.get('hello'); // undefined

You cannot pass an object to the map constructor. To convert an object to a map, you must use the Object.entries() function to convert the object to an array of key/value pairs.

const obj = { answer: 42 };
// This throws an error because objects are **not** iterable
// "TypeError: undefined is not a function"
new Map(obj);

// Works, you need to use `Object.entries()` to convert the object
// to a key/value array
const map = new Map(Object.entries(obj));
map.get('answer'); // 42

Iterating Over a Map

You can iterate over a map's keys or key/value pairs using a for/of loop. Maps have a keys() function that gives you the map's keys, and an entries() function that gives you the map's key/value pairs.

const map = new Map([
  ['key1', 1],
  ['key2', 2],
  ['key3', 3]
]);

for (const key of map.keys()) {
  // 'key1', 'key2', 'key3'
  key;
}

for (const [key, value] of map.entries()) {
  // 'key1', 'key2', 'key3'
  key;
  // 1, 2, 3
  value;
}

Did you find this tutorial useful? Say thanks by starring our repo on GitHub!

More Fundamentals Tutorials