DefaultWeakMap
A weak map that automatically creates values for missing keys using a factory function.
Similar to DefaultMap but uses WeakMap as the base, allowing garbage collection of keys.
@example
// Store metadata for DOM elements without preventing garbage collection
const elementMetadata = new DefaultWeakMap<HTMLElement, { clicks: number; hovers: number }>(
() => ({ clicks: 0, hovers: 0 })
)
const button = document.querySelector('button')!
const div = document.querySelector('div')!
elementMetadata.get(button).clicks++
elementMetadata.get(button).clicks++
elementMetadata.get(div).hovers++
console.log(elementMetadata.get(button)) // { clicks: 2, hovers: 0 }
console.log(elementMetadata.get(div)) // { clicks: 0, hovers: 1 }
// When elements are removed from DOM and not referenced,
// their metadata can be garbage collected
@example
// Cache computed properties for objects
const computedCache = new DefaultWeakMap<object, Map<string, any>>(
() => new Map()
)
function getOrCompute(obj: object, key: string, compute: () => any) {
const cache = computedCache.get(obj)
if (!cache.has(key)) {
cache.set(key, compute())
}
return cache.get(key)
}
const user = { name: 'Alice', age: 30 }
const displayName = getOrCompute(user, 'displayName', () => user.name.toUpperCase())
const birthYear = getOrCompute(user, 'birthYear', () => new Date().getFullYear() - user.age)
console.log(displayName) // 'ALICE'
console.log(birthYear) // 1994 (or current year - 30)
@example
// Initialize with existing entries
const obj1 = {}
const obj2 = {}
const objectData = new DefaultWeakMap<object, string[]>(
() => [],
[
[obj1, ['tag1', 'tag2']],
[obj2, ['tag3']]
]
)
objectData.get(obj1).push('tag4')
console.log(objectData.get(obj1)) // ['tag1', 'tag2', 'tag4']
console.log(objectData.get(obj2)) // ['tag3']
const obj3 = {}
console.log(objectData.get(obj3)) // [] (auto-created)
@example
// Track event listeners per element using both DefaultWeakMap and DefaultMap
const eventListeners = new DefaultWeakMap<EventTarget, DefaultMap<string, Function[]>>(
() => new DefaultMap<string, Function[]>(() => [])
)
function addListener(target: EventTarget, event: string, handler: Function) {
eventListeners.get(target).get(event).push(handler)
}
const element = document.createElement('button')
addListener(element, 'click', () => console.log('clicked'))
addListener(element, 'click', () => console.log('also clicked'))
addListener(element, 'hover', () => console.log('hovered'))
console.log(eventListeners.get(element).get('click').length) // 2
console.log(eventListeners.get(element).get('hover').length) // 1
// No need for has() checks or null assertions - everything auto-initializes!
class DefaultWeakMap<K extends WeakKey, V> extends WeakMap<K, V> { }
constructor(defaultFactory: () => V, entries?: readonly (readonly [K, V])[] | null);
private readonly defaultFactory;
get(key: K): V;