JavaScript developers often use plain objects as key-value stores, but the Map
data structure offers several compelling advantages. Let's explore why you might want to choose Map
over a dynamic object in your next project.
1. Key Types Flexibility
One of the most significant advantages of Map
is its ability to use any value as a key, not just strings and symbols.
// With Objects, keys are always converted to strings
const obj = {};
obj[true] = "value1";
obj[1] = "value2";
obj[{ key: 1 }] = "value3";
console.log(Object.keys(obj));
// Output: ["true", "1", "[object Object]"]
// With Map, keys maintain their type
const map = new Map();
map.set(true, "value1");
map.set(1, "value2");
map.set({ key: 1 }, "value3");
console.log([...map.keys()]);
// Output: [true, 1, { key: 1 }]
2. Size Management
Maps provide a built-in size property, while objects require manual calculation.
// With Objects
const obj = { a: 1, b: 2, c: 3 };
const size = Object.keys(obj).length; // Requires conversion to array
console.log(size); // 3
// With Map
const map = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
console.log(map.size); // 3, direct access
3. Better Iteration Performance
Maps are designed for frequent additions and removals of key-value pairs, with better performance for iteration.
// Performance test
const iterations = 1000000;
// Object
const obj = {};
console.time('Object');
for (let i = 0; i < iterations; i++) {
obj[`key${i}`] = i;
}
for (const key in obj) {
const value = obj[key];
}
console.timeEnd('Object');
// Map
const map = new Map();
console.time('Map');
for (let i = 0; i < iterations; i++) {
map.set(`key${i}`, i);
}
for (const [key, value] of map) {
// Direct value access
}
console.timeEnd('Map');
4. Clear Methods for Common Operations
Map provides clear, purpose-built methods for common operations.
// Map operations
const map = new Map();
// Adding entries
map.set('key1', 'value1');
map.set('key2', 'value2');
// Checking existence
console.log(map.has('key1')); // true
// Getting values
console.log(map.get('key1')); // 'value1'
// Deleting entries
map.delete('key1');
// Clearing all entries
map.clear();
// Compare with Object
const obj = {};
// Adding entries
obj.key1 = 'value1';
obj['key2'] = 'value2';
// Checking existence
console.log('key1' in obj); // true
// or
console.log(obj.hasOwnProperty('key1')); // true
// Getting values
console.log(obj.key1); // 'value1'
// Deleting entries
delete obj.key1;
// Clearing all entries
for (const key in obj) {
delete obj[key];
}
5. No Prototype Chain Issues
Maps don't have inheritance issues that can plague objects.
const obj = {};
console.log(obj.toString); // [Function: toString]
console.log(obj.hasOwnProperty('toString')); // false
const map = new Map();
console.log(map.get('toString')); // undefined
console.log(map.has('toString')); // false
6. Easy Iteration with Multiple Methods
Maps offer various built-in iteration methods.
const map = new Map([
['name', 'John'],
['age', 30],
['city', 'New York']
]);
// Iterate over entries
for (const [key, value] of map) {
console.log(`${key}: ${value}`);
}
// Iterate over keys
for (const key of map.keys()) {
console.log(key);
}
// Iterate over values
for (const value of map.values()) {
console.log(value);
}
// Using forEach
map.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
When to Still Use Objects
While Maps are powerful, objects are still preferable in certain scenarios:
- When you need JSON serialization (Maps aren't automatically serializable)
- When working with simple property access
- When you need to use object spread operator
- When dealing with JSON APIs
// JSON serialization
const obj = { name: 'John', age: 30 };
const jsonStr = JSON.stringify(obj); // Works fine
const map = new Map([['name', 'John'], ['age', 30]]);
const jsonStr2 = JSON.stringify(map); // Results in '{}'
// However, you can convert Map to Object for serialization
const mapAsObj = Object.fromEntries(map);
const jsonStr3 = JSON.stringify(mapAsObj); // Works fine
Conclusion
Maps are the better choice when you need:
- Non-string keys
- Frequent additions and removals
- Easy size tracking
- Better iteration performance
- Clear and consistent methods for common operations
- Freedom from prototype chain concerns
Consider your use case carefully, but don't be afraid to reach for Map
when these benefits align with your needs.
Top comments (2)
As we can assume by their names,
json
is a Javascipt Object Notation and map is a map we know. We can use a JSON object as a JSON object as it is. However, we have to convert from json to map if we want to json as a map. There is one more step to use them from json. As we use JSON, we can reduce an uncessary process, especially, where converting between json and map hapeen frequently. I think that's maybe why people use just json itself but I agree that map is clear to use when we that as a map, because map is map. I'm not sure what I'm saying sounds make sense tho 😂Which is good for higher rate of data, suppose 1Million entries,
As both will use most size of memory
And isn't map performance affected by size of data, cause when map will be full it'll make new map of more size, then copy all elements in that map?