Deep dive into JavaScript Map Object

Eric Sarpong
Analytics Vidhya
Published in
5 min readJul 28, 2020

JavaScript has come a long way from its inception to present. Over the course of years JavaScript has gradually introduced new features to the language to make it more robust.

The introduction of ES6 brought in a plethora of new features to JavaScript, which has greatly made the lives of developers much easier. One of those features is the Map data structure.

The JavaScript map data structure is a powerful tool to use when you need a collection of strictly key/value pairs, but need more functionalities than what a regular JavaScript object provides.

What is a map?

As stated in the previous paragraph, a map in computer science term is a data structure that holds a key/value pair. A map allows for fast key look up in a data structure, easily accessing a value in 0(1) access time. Maps have been in existence in other languages such as Java and C# for quite some time now.

Let’s start with some basic operations of a map:

creating a Map

You create a map by calling its constructor and instantiating it with the new keyword. There are two ways to accomplish this.

  1. You can instantiate a map with a no arguments constructor.
let myMap = new Map()

This will create a new map with no default values and size of 0.

console.log(myMap.size);
//0

2. The other option to instantiating a map, is to pass in values to the constructor

let myMap = new Map([[1, 'one'],[2, 'two'],[3, 'three'],]);

This will create a map of default size of three, and the passed arguments as key/value pairs.

Adding new elements to a Map

You add new elements to a map by calling the set method, which takes two
arguments — a key and a value.

let myMap = new Map()
myMap.set('Ford', 'American');
myMap.set('Kantanka', 'Ghana');
myMap.set('Toyota', 'Japan');
myMap.set('Volkswagen', 'German');

Retrieving elements from a Map

Retrieving an element from a map is as simple as calling the get method of the map with the key as the argument. Continuing from the “set” example above:

console.log(myMap.get('Kantanka')); //Ghana
console.log(myMap.get('Toyota')); //Japan
console.log(myMap.get('Ford')); //American
console.log(myMap.get('Volkswagen')); //American

If you try to access a key that does not exist in the map, an undefined will be returned

console.log(myMap.get('unknown')); //undefined

Beware: If you assign a value of an object type to a key, it will be of a reference type, meaning any change made to that object will be reflected in the map.

let myMap = new Map();const car = {
name: 'Impala'
Year: '2020'
}
myMap.set('myNewCar', car);
console.log(myMap.get('myNewCar')); // {name: "Impala", year:"2020"}
car.name = 'Malibu';
car.year = '2015';
console.log(myMap.get('myNewCar')); // {name: "Malibu", year:"2015"}

Map vs regular Objects

Earlier I mentioned that Map are a key/value pair data structure. The same can be said for regular objects in JavaScript, but there are some differences between the two should be pointed out:

  • JavaScript(JS) Objects are a collection of properties, JS objects only accepts two types of property types String and Symbols, if you try to pass any other types as keys to a JS object, it will convert them to a string.
//Regular JS Object
const car = {
name: 'Impala',
year: '2020',
true: 1
}
console.log(Object.keys(car)); //["name", "year", "true"]

Whereas a Map will accept any type of key and will NOT convert it to a string. A map can even accept a function as it’s key.

let myMap = new Map()
myMap.set('Ford', 'American');
myMap.set('Kantanka', 'Ghana');
function randomKey() {
return 'key1'
}
myMap.set(randomKey(), 'generated random key');
console.log(myMap.get('key1')); //generated random key
  • Maps are iterable, which means you can use loops such as forEach or for…of to iterate to iterate over it’s values.
let myMap = new Map()
myMap.set('Ford', 'American');
myMap.set('Kantanka', 'Ghana);
myMap.set('Toyota', 'Japan');
myMap.set('Volkswagen', 'German');
//Using forEach loop
myMap.forEach((value, key) => {
console.log(key, value);
})
//Ford American
//Kantanka Ghana
//Toyota Japan
//Volkswagen German

-----------------------------------------------------------------
//Using for...of to iterate over valuesfor (let value of myMap.values()) {
console.log(value);
}
//American
//Ghana
//Japan
//German

As for JavaScript objects, they are not iterable by default. Trying to iterate over a JS object using the above loops(forEach, for…of) will throw a TypeError execption

const car = {
name: 'Impala',
year: 2020
}
for (let value of car) {
console.log(value);
}
//Uncaught TypeError: car is not iterable

The only way to iterate over objects is through its keys using for…in loop or Object.keys

const car = {
name: 'Impala',
year: 2020
}
//Using for...in loop
for (let key in car) {
console.log(key);
}
//name
//year
----------------------------------------------------------------
//Using Object.keys()
console.log(Object.keys(car));
//["name", "year"]
  • A map keeps track of it’s collection size, and you can use the size method to retrieve the current size of the map which is of O(1) access time.
let myMap = new Map()
myMap.set('Ford', 'American');
myMap.set('Kantanka', 'Ghana');
console.log(myMap.size); //2

A JS object does not keep track of it’s size and the only way to get the size of an object is to iterate over it’s keys, which is of O(N) access time.

  • Keys inserted into maps maintain their order. When you iterate over a map it will return the keys in the order in which they were inserted.
let myMap = new Map()
myMap.set('Ford', 'American');
myMap.set('Kantanka', 'Ghana);
myMap.set('Toyota', 'Japan');
myMap.set('Volkswagen', 'German');
myMap.forEach((value, key) => {
console.log(key);
})
//Ford
//Kantanka
//Toyota
//Volkswagen

Regular JS objects did not maintain key order until the introduction of ES6. But even with ES6, JS objects will only preserve keys of strings and symbols in the correct order, any other types that were converted to string will not be kept in the correct order

const car = {
name: 'Impala',
year: '2020',
true: 'boolean',
7: 'just random number'
}
console.log(Object.keys(car)); //["7", "name", "year", "true"]

The above points shows how different a Map is from a regular object and also advantages it has over plain old JavaScript objects.

Other useful Map methods

  • clear(): Removes all key/value pairs from the map instance.
  • delete(key): Will return a boolean value of true, if the passed argument existed in the map instance and has been removed, false otherwise.
  • entries(): Returns a new iterator object that contains an for each of the elements in the map instance and also in it’s insertion order.
  • iterator(): Returns a new Iterator object that contains an array of key/value pairs for each element in the Map object in it’s insertion order.

When to use a map

  • A map should be considered when key values of different data types aside from Strings and Symbols are required.
  • A map should be considered when you require key/value pairs to be iterable.
  • Maps have more useful functions for insert and removals which makes it easier to use over object in cases where insertions and deletions are a must.

Have you been using the Map object or are new to it? Leave a comment below on your thoughts and use cases of the Map object.

If you enjoyed this article make sure to hit the clap button and check out my other articles below!

--

--

Eric Sarpong
Analytics Vidhya

Director of Frontend Technology, with a passion for writing about Software Development, Angular, JavaScript, TypeScript, C#, Java and many more.