JavaScript WeakMap y WeakSet
En el capítulo Garbage Collection, se afirmó que el motor de JavaScript puede almacenar un valor en la memoria una vez que es alcanzable.
Aquí hay un ejemplo:
Como regla general, las propiedades o elementos de estructuras de datos como un objeto o un array son alcanzables y se mantienen en la memoria una vez que esa estructura de datos está en la memoria. Por ejemplo, después de poner un objeto en un array, existirá mientras exista el array.
Aquí tienes un ejemplo:
Correspondientemente, al aplicar un objeto como la clave en un Map regular, existirá mientras exista el mapa.
Un ejemplo se vería así:
A continuación, vamos a cubrir WeakMap, que es completamente diferente y no se abstiene de la recolección de basura de los objetos clave.
WeakMap
La diferencia principal entre Map y WeakMap es que la clave de WeakMap no puede ser valores primitivos. Deben ser objetos, como en el ejemplo de abajo:
La iteración y los métodos keys(), values(), entries() no son compatibles con WeakMap.
Los métodos que sí son compatibles con WeakMap son los siguientes: weakMap.get(key), weakMap.set(key, value), weakMap.has(key) y weakMap.delete(key).
weakMap.delete(key)
El almacenamiento de datos adicionales es el uso principal para WeakMap. WeakMap es especialmente útil para almacenar datos asociados a una librería de terceros. Por ejemplo, considere almacenar los datos en un WeakMap, con un objeto como clave. Una vez que el objeto se recolecta como basura, los datos también desaparecerán automáticamente como se muestra a continuación:
let weakMap = new WeakMap();
let obj = {
name: "test"
};
key = weakMap.set(obj, "test docs");
// if obj disappears, test docs will be automatically destroyed
Ahora, imagina tener un código que mantiene un recuento de visitas para los usuarios. Esta información se conserva dentro de un mapa, con un objeto de usuario como clave y el recuento de las visitas como valor.
Después de que un usuario se va, tienes la intención de dejar de almacenar su recuento de visitas.
Primero, veamos un ejemplo de función de conteo con Map. Se verá así:
Por lo tanto, al eliminar a los usuarios, es necesario limpiar visitsCountMap. De lo contrario, se almacenará en la memoria de manera indefinida.
Sin embargo, limpiar de esta manera puede llegar a ser una tarea molesta a veces. Si quieres evitarlo, puedes recurrir a WeakMap. Aquí tienes un ejemplo de cómo usar WeakMap en lugar de ese tipo de limpieza:
Ahora, ya no es necesario limpiar visitsCountMap.
Acerca del Caché
El caché ocurre cuando se debe recordar (almacenar en caché) el resultado de una función para reutilizarlo más tarde al llamar al mismo objeto.
Se puede usar Map para almacenar resultados de la siguiente manera:
En caso de llamar a process(obj) con el mismo objeto varias veces, calculará el resultado sólo la primera vez. Después, tomará la información de la caché.
La única desventaja del caché es que necesitas limpiar la caché una vez que ya no necesites el objeto.
Reemplazar Map con WeakMap resolverá el problema. La información en caché se eliminará automáticamente de la memoria una vez que el objeto se haya recolectado como basura.
Para ser más precisos, consideremos el ejemplo de abajo:
// cache.js
let cache = new WeakMap();
// calculate and remember the result
function process(obj) {
if (!cache.has(obj)) {
let res = /* calculate the result for */ obj;
cache.set(obj, res);
}
return cache.get(obj);
}
// main.js
let obj = { /* some object */ };
let res1 = process(obj);
let res2 = process(obj);
// later, when object is no longer needed:
obj = null;
// Can not get cache.size because it is WeakMap,
// but it is 0 or soon will be 0
//Once object gets garbage collected, the cached data will also be cleaned
WeakSet
WeakSet se considera equivalente a Set. Sin embargo, sólo los objetos y no los primitivos pueden añadirse a WeakSet.
Un objeto se encuentra en el conjunto mientras es alcanzable en otro lugar.WeakSet también admite has, add y delete. Pero no se admiten iteraciones ni los métodos size y keys().
También puede servir como almacenamiento adicional para datos, pero no para datos arbitrarios. Aquí hay un ejemplo de cómo agregar lenguajes a WeakSet para llevar un registro de los que crearon el sitio:
Hay una limitación significativa en WeakMap y WeakSet: no hay iteraciones. Tampoco existe la habilidad de recibir todo el contenido actual.
Resumen
En este capítulo, cubrimos WeakMap y WeakSet.
Para resumir, podemos afirmar que WeakMap se considera una colección similar a Map, que solo permite que los objetos sean claves. Los elimina junto con el valor asociado cuando se vuelven inaccesibles.
WeakSet se considera una colección similar a Set, que almacena solo objetos y los elimina cuando se vuelven inaccesibles.
Ambas colecciones no admiten propiedades ni métodos que no se refieren a todas las claves o al recuento de las mismas. Sólo permiten operaciones individuales.
Hora del Cuestionario: ¡Pon a Prueba Tus Habilidades!
¿Listo para desafiar lo que has aprendido? Sumérgete en nuestros cuestionarios interactivos para una comprensión más profunda y una forma divertida de reforzar tu conocimiento.