DEV Community

Cover image for How Maps solve the limitations of Objects in JavaScript
Jay Cruz
Jay Cruz

Posted on

How Maps solve the limitations of Objects in JavaScript

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:

const map = new Map([
    ["key", "value"]
]);
Enter fullscreen mode Exit fullscreen mode

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.

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:

const obj = {
    1: 2,
    0: false,
    "Greet": "Hello World",
    a: "b",
    c: "c"
}
Enter fullscreen mode Exit fullscreen mode

When we log obj to the console it displays a different ordering from what we originally declared it with:

{0: false, 1: 2, Greet: 'Hello World', a: 'b', c: 'c'}
Enter fullscreen mode Exit fullscreen mode

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

const map = new Map([
    [1, 2],
    [0, false],
    ["Greet", "Hello World"],
    ["a", "b"],
    ["c", "c"]
]);
Enter fullscreen mode Exit fullscreen mode

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

{1 => 2, 0 => false, 'Greet' => 'Hello World', 'a' => 'b', 'c' => 'c'}
Enter fullscreen mode Exit fullscreen mode

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.

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

Object.entries(obj).length; // 3
Enter fullscreen mode Exit fullscreen mode

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.

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

console.log(map.size); // 3
Enter fullscreen mode Exit fullscreen mode

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.

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

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

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

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

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

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

map.forEach(value => console.log(value));
// one
// two
// three
Enter fullscreen mode Exit fullscreen mode

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.

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
Enter fullscreen mode Exit fullscreen mode

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.

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

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

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!

Top comments (0)

Some comments have been hidden by the post's author - find out more