How Maps solve the limitations of Objects in JavaScript
Tags: javascript, programming, webdev, tutorial
Published: 2021-11-19 11:51:22

###### An overview of Maps in JavaScript and how they can make up for limitations that come with using objects.


In JavaScript, objects are one of the most commonly used data structures. They provide you with a way to organize and store data as key/value pairs. While this is the case they also come with some limitations that are worth pointing out. In this article, we’ll be going over what those limitations are and show how using the Map object vs regular objects can be more effective.

## What is the Map object?

The Map object was first introduced with the ES6 version of JavaScript. Like regular objects, they can contain key, value pairs and allow you to add, retrieve, remove, and check for those keys and values.

To create a new instance of the Map object we can do so as the following:
```javascript
const map = new Map([
    ["key", "value"]
]);
```

There are several built-in properties and methods that come with an instance of the Map object. These include but are not limited to some of the more common ones such as the following:

* `.set()` - Adds key, value pairs with the first argument being the key and second being the value `.set(key, value)`

* `.get()` - Retrieves a value linked to a key by passing in the specified key as the only argument `.get(key)`

* `.delete()` - Removes a key, value pair identified by the passed-in key name `.delete(key)`

* `.has()` - Checks whether or not a key, value pair exists and returns a boolean value. Takes in the key as the only argument `.has(key)`

* `.size` - Returns an integer representing the number of key/value pairs contained within the Map object

*For more about the Map object’s built-in properties and methods check out this [link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#constructor).*

## Using Map to avoid limitations of using objects

To show how using the Map object can solve for limitations that arise when using objects let’s go over what these limitations are and how we can avoid them using maps.

### Objects are not guaranteed to be ordered

Although this has changed since JavaScript has updated to ES6 the ordering for the key/value pairs of a regular object can still be unreliable.

Take the following object we declared for example:
```javascript
const obj = {
    1: 2,
    0: false,
    "Greet": "Hello World",
    a: "b",
    c: "c"
}
```
When we log `obj` to the console it displays a different ordering from what we originally declared it with:

```javascript
{0: false, 1: 2, Greet: 'Hello World', a: 'b', c: 'c'}
```

When we try declaring the same key/value pairs with a map,

```javascript
const map = new Map([
    [1, 2],
    [0, false],
    ["Greet", "Hello World"],
    ["a", "b"],
    ["c", "c"]
]);
```

we instead get the original order in which they were declared.

```javascript
{1 => 2, 0 => false, 'Greet' => 'Hello World', 'a' => 'b', 'c' => 'c'}
```

### No method to quickly determine the length or size of an object

With an object, we determine the size manually by iterating over the object using a for loop and a counter or using the `Object.entries()` method along with `.length`.

```javascript
const obj = {
    1: "one",
    2: "two",
    3: "three"
};

Object.entries(obj).length; // 3
```

When we need to find out the number of key/value pairs in a Map object we can use the `.size` property to easily get it.

```javascript
const map = new Map([
    [1, "one"],
    [2, "two"],
    [3, "three"]
]);

console.log(map.size); // 3
```

### **Map object is naturally iterable, Object is not**

To iterate over objects we usually use a for..in loop to manually get each key and value.

```javascript
// obj = {1: 'one', 2: 'two', 3: 'three'}

for (let key in obj) {
    console.log(key, ": ", obj[key]);
    // 1: one
    // 2: two
    // 3: three
}
```

Note however that `Object.keys()` and `Object.values()` or `Object.entries()` can also be used to make an object iterable.

```javascript
Object.entries(obj)
    .forEach(entry => console.log(entry[0], ": ", entry[1]));
    // 1: one
    // 2: two
    // 3: three
```

A map object can be easily and directly iterated over with methods like `.forEach()` to access each value.

```javascript
// map = {1 => 'one', 2 => 'two', 3 => 'three'}

map.forEach(value => console.log(value));
// one
// two
// three
```

### Key types of objects can be only string or symbol

When declaring Javascript objects, the only types we can use as the key is a string or a symbol.

```javascript
const obj = {
    ["key"]: "value"
};

console.log(obj); // automatically converts array key to a symbol: {key:'value'}

const obj2 = {
    ["key"]: "value",
    function key(), "Value"
};

console.log(obj2); // throws an error
```

While keys for a regular JavaScript object can only be either a string or a symbol the same does not go for Map objects. For the Map object, its keys can be of any type including functions, objects, and arrays.

```javascript
const map = new Map([
    [ ["key"], "value" ],
    [ function key() {}, "value" ],
    [ { "a": 1 }, "b" ],
]);

console.log(map); 
// {Array(1) => 'value', ƒ => 'value', {…} => 'b'}
```

## Summary

In Javascript, Maps are very useful data structures. They provide more flexibility than regular objects do, for example, Maps give us the ability to use any data type as a key while also maintaining the original ordering they’re declared with.

Next time you’re reaching for that plain ol’ JavaScript object to store some sort of complex data, consider using a map. Depending on the use case it may just serve you better!

* [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#objects_vs._maps)

* [Objects vs Maps](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#objects_vs._maps)