Saltar al contenido principal
12Sets y Maps

WeakSet y WeakMap

Además de Set y Map, JavaScript tiene dos primos hermanos con un comportamiento especial: WeakSet y WeakMap. La palabra clave aquí es weak (débil), y tiene que ver con la memoria.

Nota

En un WeakMap y un WeakSet las referencias a los objetos guardados son débiles: si no queda ninguna otra referencia a ese objeto, el recolector de basura puede eliminarlo, y desaparecerá también de la colección.

Recordatorio: el recolector de basura

JavaScript libera automáticamente la memoria de los valores que ya no se usan en ningún sitio. A ese proceso lo llamamos garbage collection (recolección de basura).

El problema es que un Map o un Set normales mantienen vivas las referencias que guardan. Aunque borres el objeto de todas las demás partes de tu código, mientras esté dentro del Map, no se liberará:

let usuario = { name: 'Dani' }

const datos = new Map()
datos.set(usuario, 'info importante')

usuario = null // ya no lo uso en ningún otro sitio...
// pero el Map SIGUE manteniendo el objeto vivo en memoria

WeakMap

Un WeakMap resuelve ese problema: si el objeto que usas como clave deja de tener otras referencias, se elimina automáticamente de la memoria y del WeakMap.

let usuario = { name: 'Dani' }

const datos = new WeakMap()
datos.set(usuario, 'info importante')

usuario = null
// ahora el objeto puede ser liberado por el recolector de basura
// y su entrada desaparecerá del WeakMap
Infografía
Map frente a WeakMap cuando ya no usas el objeto
5.En el WeakMap la referencia es débil y no cuenta: el objeto se libera y su entrada desaparece sola.
Paso 5 de 5

Limitaciones del WeakMap

A cambio de esa magia, un WeakMap tiene reglas estrictas:

  • Sus claves solo pueden ser objetos (no string, ni number...).
  • No es iterable: no puedes recorrerlo con for...of, ni usar .keys(), .values() o .size.
  • Solo tienes los métodos .set(), .get(), .has() y .delete().
const wm = new WeakMap()

wm.set('texto', 1) // ❌ TypeError: la clave debe ser un objeto

WeakSet

Un WeakSet es la versión débil de Set: una colección de objetos únicos cuyas referencias no impiden que se liberen de memoria.

const visitados = new WeakSet()

let nodo = { id: 1 }
visitados.add(nodo)

console.log(visitados.has(nodo)) // true

nodo = null
// el objeto podrá ser recolectado y saldrá del WeakSet

Igual que el WeakMap, solo admite objetos, no es iterable y solo ofrece .add(), .has() y .delete().

¿Cuándo los uso?

La verdad es que en el día a día los usarás poco. Son útiles en casos muy concretos:

  • Guardar datos asociados a un objeto sin provocar fugas de memoria (por ejemplo, metadatos privados de una instancia).
  • Marcar objetos que ya hemos procesado, sin evitar que se liberen después.
Nota

No te agobies si ahora mismo no encuentras dónde usarlos. Lo importante es saber que existen y entender la idea: referencias débiles que no impiden la recolección de basura. Para casi todo lo demás, Set y Map son tu opción.

¡Y con esto cierras la sección de Sets y Maps! 🎉