A plain object and array cover most needs, but four more built-in structures solve specific problems neither one does well.
A plain object's keys are always converted to strings. A Map allows a key of any type — an object, a function, even another Map.
const userRoles = new Map()
const user1 = { name: 'Sam' }
userRoles.set(user1, 'admin')
userRoles.set('guest', 'viewer')
userRoles.get(user1) // "admin"
userRoles.size // 2
for (const [key, value] of userRoles) {
console.log(key, value)
}A Set stores a list of values with duplicates automatically removed.
const uniqueTags = new Set(['js', 'css', 'js', 'html', 'css'])
console.log(uniqueTags) // Set(3) { 'js', 'css', 'html' }
console.log(uniqueTags.size) // 3
uniqueTags.add('react')
uniqueTags.has('css') // true
uniqueTags.delete('html')const numbers = [1, 2, 2, 3, 3, 3]
const unique = [...new Set(numbers)]
// [1, 2, 3]WeakMap and WeakSet work like their non-weak counterparts, but only accept objects as keys/values, and don't prevent those objects from being garbage collected (covered in the earlier Memory Management lesson) once nothing else references them. This makes them useful for attaching extra data to an object without causing a memory leak.
const cache = new WeakMap()
function process(obj) {
if (cache.has(obj)) return cache.get(obj)
const result = expensiveComputation(obj)
cache.set(obj, result)
return result
}
// If obj is later discarded elsewhere in the code,
// its cache entry can be garbage collected too — a regular Map would hold it forever| Structure | Keys/values | Iterable? | Prevents garbage collection? |
|---|---|---|---|
| Map | Any type | Yes | Yes |
| Set | Any type (values only) | Yes | Yes |
| WeakMap | Objects only | No | No |
| WeakSet | Objects only | No | No |