Map in ES6 JavaScript

Introduction

There is a data structure in JavaScript ES6 similar to objects that I have never fully understood. — Map. This article mainly compares familiar objects with Map to distinguish the characteristics and usage timing of Map.

Syntax

// Init
const map = new Map([
[1, 'apple'],
[2, 'orange'],
]);
// Set - Add key and value
map.set(3, 'banana');
// Get value by key
map.get(3);
// Delete by key
map.delete(3);
// Clear all data
map.clear();
// Check if key exists
map.has(2);
// Get all keys
map.keys();
// Get all values
map.values();
// Get key-value pairs
map.entries();
// Get data length
map.size;
// Iteration for - for loop
for (const [key, value] of map) {
console.log({ key, value });
}
// Iteration forEach - forEach loop
map.forEach((value, key) => {
console.log({ key, value });
});
// Swap keys and values
const swapMap = Array.from(map).reduce((acc, [key, value]) => acc.set(value, key), new Map());

Advantages of Map Compared to Objects

  1. No Legacy Issues: Apart from the specially stored keys, Map does not have any keys, making it clearer and more concise compared to Object.
const myMap = {};
myMap.valueOf; // => [Function: valueOf]
myMap.toString; // => [Function: toString]
myMap.hasOwnProperty; // => [Function: hasOwnProperty]
myMap.isPrototypeOf; // => [Function: isPrototypeOf]
myMap.propertyIsEnumerable; // => [Function: propertyIsEnumerable]
myMap.toLocaleString; // => [Function: toLocaleString]
myMap.constructor; // => [Function: Object]

Additionally, when retrieving values, for example, books[id], you might need to worry about whether the id key actually exists in books, so you need to check for existence before retrieving, like this:

// Method to check if an object has a key
if (books.hasOwnProperty(id)) {
}
// Method to check if an object has a key in certain cases
if (Object.prototype.hasOwnProperty.call(books, id)) {
}

However, in Map, you can directly use the corresponding method to query, and you can ensure that no extra keys exist by default. Check out the following concise syntax!

myMap.get(key);
for (const [key, value] of myMap) {
}
  1. Allow any type of key: The keys of a Map can be of any type, including objects, functions, and primitive types (strings, numbers, etc.). In contrast, the keys of an object can only be strings or symbols (Symbol🔗).

  2. Explicit order: A Map retains the insertion order of key-value pairs, allowing iteration in the order they were inserted, which objects cannot guarantee. This characteristic of explicit order also makes Map traversal more efficient. For details, you can check out builder.io’s online quiz🔗.

  3. Security: Setting user-provided key/value pairs on an object may allow malicious injection of crafted objects into the program (Object Injection Attacks🔗), altering the program’s logic or executing unintended operations, while using Map methods can safely avoid this situation.

Disadvantages of Map Compared to Objects

  1. Learning curve: Although Map is simple to use, it is less frequently encountered, so those unfamiliar with it may incur additional learning costs.
  2. Memory overhead: Due to the implementation details of Map, it typically consumes more memory than objects when storing the same number of key-value pairs.
  3. JSON support: Objects can be directly converted to JSON format, while Maps require additional processing to serialize to JSON format.
// Convert Object to JSON
const obj = { key: 'value' };
const jsonString = JSON.stringify(obj);
// Convert Map to JSON
const map = new Map();
map.set('key', 'value');
// Needs to be converted to an object or array before converting to JSON
const mapToObject = Object.fromEntries(map);
const mapToJsonString = JSON.stringify(mapToObject);

When to Use

In summary, Map can be considered as an object for frequent read and write operations, offering better performance and clearer syntax, while objects can be used to store fixed key-value pairs when frequent read and write is not needed.

Further Reading