Advantages of a JavaScript Map 
Tags: javascript
Published: 2020-03-07 01:38:06

I wrote a previous blog post about [JavaScript Set objects](https://dev.to/katkelly/ditching-dupes-with-a-set-4cf3) so I naturally wanted to follow it up with a post about JavaScript Map objects. Sets and Maps could be considered distant cousins or estranged siblings to the more popular and workhorse Arrays and Objects, and a Map in particular is like a hybrid Object/Array (okay, I may be the only one who considers this). 

Introduced with the updates in ECMAScript 2015, **a Map is an iterable keyed collection that remembers the original insertion order of the keys.** It will always maintain this order of entries. 

###Similarities to Objects

Objects are similar to Maps, as both data structures allow you to set key/value pairs and be able to retrieve those values. You can also delete keys and determine whether there is something currently stored at a key. **MDN Web Docs states Objects have been used as Maps historically**, as there were no built-in alternatives. 

###Differences from Objects

The following differences between a Map and an Object may make a Map more preferable in specific cases:

####Key Differences (get it?)
**Retaining the insertion order is a big advantage of a Map, as a Map will maintain the order of entries.** Objects do not have a guaranteed order, however, MDN Docs indicate that “Since ECMAScript 2015, objects do preserve creation order for string and Symbol keys. In JavaScript engines that comply with the ECMAScript 2015 spec, iterating over an object with only string keys will yield the keys in order of insertion."

Regarding default keys, **a Map will only contain what you explicitly put into it so there are no surprise default keys.** Since an Object has a prototype, it contains default keys that may counter your own keys so this is something to keep in mind.

In a Map, **there is more flexibility with key values, as a key can be any value such as functions, objects, and primitives.** In an Object, a key can only be a string or symbol. Depending on how you are storing your data, Map’s flexibility with more data types could be useful.

Though keys in Maps are unique, when using an Object as a key the Map will use the reference to the Object to check equality. Something to keep in mind is if two objects have the same value(s) but do not share the same reference they will not be considered equal.

```javascript
const obj1 = {'favorite': 'New Zealand'};
const obj2 = {'favorite': 'New Zealand'};
obj1 === obj2; // false
const map = new Map();
map.set(obj1, 2); // Map { {favorite: 'New Zealand'} => 2 }
map.set(obj2, 2); // Map { {favorite: 'New Zealand'} => 2, {favorite: 'New Zealand'} => 2 }
map.set({'favorite': 'New Zealand'}, 2); // Map { {favorite: 'New Zealand'} => 2, {favorite: 'New Zealand'} => 2, 
//{favorite: 'New Zealand'} => 2 }
```
####Other Important Differences
Other advantages of a Map include the **`size` property, an easy way to get the number of items** in the Map. With an Object, you would be on your own to figure out its size. 

**Iterating over a Map can be done directly**, unlike an Object where you would have to obtain the keys/values/entries, typically as an Array, and then iterate over those values. 

The **performance of frequent additions or even removals of key-value pairs can be advantageous** in a Map versus an Object, which is not optimized for these actions.

###Getting Started

![guy with map](https://media.giphy.com/media/U4YEoSRgz5JtebnYqH/giphy.gif)

Below is how to initialize a new Map:

```javascript
const travelMap = new Map(); 
travelMap; // Map {}
```

You can also initialize a Map with an existing Array (using a nested Array) or an Object.

```javascript
const myArray = [
  ['Asia', 6], 
  ['Europe', 6], 
  ['Other', 3]
];
const travelMap = new Map(myArray);

const myObject = {
  'Asia': 6, 
  'Europe': 6, 
  'Other': 3
};
const travelMap = new Map(Object.entries(myObject));

travelMap; // Map {'Asia' => 6, 'Europe' => 6, 'Other' => 3}
```

###Map Properties and Methods

To add new key/value pairs to the Map, the `set()` method takes two arguments, the key and the value,  and will return the Set object. The `size()` property returns the number of key/value pairs in the Map:

```javascript
Map.prototype.set(key, value);

travelMap.set('Asia', 6); // Map {'Asia' => 6}
travelMap.set('Europe', 6); // Map {'Asia' => 6, 'Europe' => 6}
travelMap.set('Other', 3); // Map {'Asia' => 6, 'Europe' => 6, 'Other' => 3}
travelMap.size; // 3
```

Other useful methods include `has()` which returns a boolean indicating whether a key exists in the Map object or not.

```javascript
travelMap.has('Asia'); //true
travelMap.has('Antarctica'); //false
```

`get()` retrieves a value in the Map using its key.

```javascript
travelMap.get('Asia'); // 6
```

`delete()` deletes the element passed in and returns the value that `has()` would have returned (`true` for a successful deletion). Using `has()` to check that since deleted element will result in a false.

```javascript
travelMap.delete('Europe'); // true
travelMap; // Map {'Asia' => 6, 'Other' => 3};
travelMap.has('Europe'); // false
travelMap.size // 2
```

And if you need to remove all of the elements in your Map, you can use `clear()`.

```javascript
travelMap.clear();
travelMap; // Map {}
```

You can iterate over key/value pairs in the Map directly using `forEach()` or a `for..of` loop. 
```javascript
//using forEach
travelMap.forEach((value, key) => 
  console.log(`Number of Countries Visited in ${key} : ${value}`)
);

//using for..of loop
for (let [key, value] of travelMap) {
  console.log(`Number of Countries Visited in ${key} : ${value}`)
};

// 'Number of Countries Visited in Asia: 6
// 'Number of Countries Visited in Europe: 6
// 'Number of Countries Visited in Other: 3
```

There are advantages to using Maps over Objects (a size property, ability to directly iterate over, and remembering the insertion order) so definitely consider the tradeoffs when determining what data structure to use. Happy coding!


Resources
[Map - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
[Understanding Map and Set in JavaScript](https://www.taniarascia.com/understanding-map-and-set-javascript/)