Skip to main content

WeakMap

Definition

A WeakMap is a collection of key-value pairs where keys must be objects. WeakMaps allow garbage collection of keys when they are no longer referenced elsewhere, making them useful for storing private data or metadata about objects.

const weakMap = new WeakMap()
weakMap instanceof WeakMap // true

Creating WeakMaps

// Empty WeakMap
const weakMap = new WeakMap()

// From array of [key, value] pairs (keys must be objects)
const obj1 = {}
const obj2 = {}
const weakMap2 = new WeakMap([
[obj1, 'value1'],
[obj2, 'value2']
])

WeakMap Methods

Setting and Getting

const weakMap = new WeakMap()
const obj = {}

// set() - adds or updates a key-value pair
weakMap.set(obj, 'value')

// get() - retrieves value by key
weakMap.get(obj) // 'value'
weakMap.get({}) // undefined (different object)

// has() - checks if key exists
weakMap.has(obj) // true

Deleting

const weakMap = new WeakMap()
const obj = {}
weakMap.set(obj, 'value')

// delete() - removes a key-value pair
weakMap.delete(obj) // true
weakMap.has(obj) // false

Key Differences from Map

FeatureWeakMapMap
Key typesObjects onlyAny type
IterationNot iterableIterable
SizeNo size propertyHas size property
Garbage collectionKeys can be GC'dKeys prevent GC
Methodsget, set, has, deleteFull API

Use Cases

Private Data Storage

const privateData = new WeakMap()

class User {
constructor(name) {
privateData.set(this, { name })
}

getName() {
return privateData.get(this).name
}
}

const user = new User('Alice')
user.getName() // 'Alice'
// privateData is not accessible from outside

Metadata Storage

const metadata = new WeakMap()

function addMetadata(obj, data) {
metadata.set(obj, data)
}

function getMetadata(obj) {
return metadata.get(obj)
}

const obj = {}
addMetadata(obj, { created: Date.now() })
getMetadata(obj) // { created: ... }

Caching with Automatic Cleanup

const cache = new WeakMap()

function getCachedValue(obj) {
if (!cache.has(obj)) {
const value = /* expensive computation */
cache.set(obj, value)
}
return cache.get(obj)
}

// When obj is garbage collected, cache entry is automatically removed

Why WeakMap?

WeakMaps allow garbage collection of keys when they're no longer referenced:

let obj = { id: 1 }
const weakMap = new WeakMap()
weakMap.set(obj, 'data')

obj = null // Object can now be garbage collected
// WeakMap entry is automatically removed

This is different from Map:

let obj = { id: 1 }
const map = new Map()
map.set(obj, 'data')

obj = null // Object cannot be garbage collected
// Map still holds reference to obj

Limitations

  1. Not iterable: Cannot use for...of, forEach(), or get size.

  2. Objects only: Keys must be objects, not primitives.

  3. No size property: Cannot check how many entries exist.

Best Practices

  1. Use for private data: Store data that should be private to objects.

  2. Use for metadata: Attach metadata to objects without modifying them.

  3. Let garbage collection work: Don't hold references to keys elsewhere if you want automatic cleanup.

  4. Don't use for iteration: If you need to iterate, use Map instead.

  5. Understand garbage collection: WeakMaps are designed to work with GC—use them when this behavior is desired.