Working with data in JavaScript often requires you to store and retrieve values efficiently. Whether you’re building a small app or developing a complex system, understanding how to use dictionaries or maps in JavaScript is a crucial skill. The purpose of this article is to walk you through how to create, manipulate, and use both plain objects and Map objects in JavaScript, ensuring your code is both effective and efficient.
TL;DR:
In JavaScript, you can create a dictionary using either a plain object ({}) or the Map object introduced in ES6. Plain objects are simpler and sufficient for many scenarios, but Map provides more flexibility, supports any type of key, and retains key insertion order. This article will guide you through creating, using, and choosing between these two options, with code examples and practical advice.
What is a Dictionary or Map in JavaScript?
A dictionary or map is a collection of key-value pairs. It’s a structure where each value is associated with a unique key that is used to retrieve it later. In other programming languages like Python or C#, dictionaries are predefined data types. JavaScript didn’t have a dedicated dictionary until ES6 introduced Map, though developers have long used plain objects to simulate dictionary behavior.
There are two main ways to create a dictionary-like structure in JavaScript:
- Using Plain Objects
- Using the Map Object
1. Using Plain Objects as Dictionaries
Plain objects use string (or symbol) keys and are great for simple lookup operations. Here’s how to define a dictionary using an object:
const fruits = {
apple: 10,
banana: 5,
mango: 7
};
console.log(fruits.apple); // Output: 10
Advantages of using objects:
- Simple syntax
- Good browser support (works in all environments)
- Efficient lookup for a limited set of string keys
Limitations of objects:
- Keys must be strings or symbols
- Unintended key collisions from the prototype chain
- Complexity in checking for whether a key truly belongs to the dictionary
To safely check if a key exists and is not inherited from Object.prototype, use:
if (Object.prototype.hasOwnProperty.call(fruits, 'apple')) {
console.log('Key exists!');
}
Tip: You can also create a “clean” object, without a prototype to avoid collisions:
const cleanDict = Object.create(null);
cleanDict.cat = 'meow';
cleanDict.dog = 'bark';
2. Using the Map Object (ES6 and Beyond)
ES6 introduced the Map object to address limitations of plain objects. Map allows keys of any type and maintains insertion order.
Creating and Using a Map
const employeeRoles = new Map();
employeeRoles.set('Alice', 'Engineer');
employeeRoles.set('Bob', 'Designer');
employeeRoles.set('Charlie', 'Manager');
console.log(employeeRoles.get('Alice')); // Output: Engineer
Advantages of using Map:
- Keys can be any type (e.g., objects, functions)
- Maintains insertion order
- Built-in size property:
employeeRoles.size - Cleaner method API:
set,get,has,delete,clear
Consider the following scenario where Map significantly outperforms objects:
const objKey = { id: 1 };
const map = new Map();
map.set(objKey, 'value tied to an object');
console.log(map.get(objKey)); // Output: value tied to an object
With an object, this breaks:
const objKey = { id: 1 };
const obj = {};
obj[objKey] = 'Oops!';
console.log(obj[objKey]); // Output: Oops!
console.log(obj); // Key is not the object, but '[object Object]'
Using a Map ensures object references remain intact and don’t convert into string keys.
Common Use Cases
Depending on your needs, either a plain object or a Map may be more suitable. Below are some common scenarios:
When to Use Objects:
- Fixed, simple key-value storage
- Keys are only strings
- Performance and size concerns are minimal
When to Use Maps:
- You need non-string keys (e.g., objects, numbers)
- Order of iteration matters
- You frequently add or remove items
- Data volume is large and optimized performance is needed
Helpful Methods and Tips
Map Methods:
map.set(key, value) // Add a new entry
map.get(key) // Retrieve value
map.has(key) // Check if key exists
map.delete(key) // Remove an entry
map.clear() // Remove all entries
map.size // Get number of entries
Object Methods:
Object.keys(obj) // Get all keys
Object.values(obj) // Get all values
Object.entries(obj) // Get entries as [key, value] pairs
Object.hasOwnProperty(key) // Check for key existence
delete obj[key] // Delete a property
Looping Through a Dictionary
Looping Through Objects:
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key]);
}
}
Looping Through a Map:
for (let [key, value] of map) {
console.log(key, value);
}
Or use built-in Map methods:
map.forEach((value, key) => {
console.log(key, value);
});
Conversion Between Objects and Maps
Object to Map:
const obj = {a: 1, b: 2};
const map = new Map(Object.entries(obj));
Map to Object:
const objFromMap = Object.fromEntries(map);
This conversion can be handy when you’re interacting with APIs or libraries that expect one format over the other.
Performance Considerations
While objects are fast and lightweight, Maps are optimized for dynamic key scenarios and frequent updates. If your project involves a lot of additions and deletions, or you need complex keys, choosing Map will give better performance.
Benchmarks often show that Map operations are faster and safer for dynamic sets of data, especially when dealing with thousands of entries.
Conclusion
Understanding JavaScript dictionaries is key to managing structured data effectively. Plain objects are a great tool for simpler applications, especially when you only need string-based keys. For more complex, feature-rich needs, Map offers a flexible and robust solution that resolves many of the quirks inherent to objects.
In the end, both tools are valuable—your choice depends on your specific use case. When in doubt, start with an object; if you hit limitations, migrating to a Map is often straightforward.
Happy coding!