Saltar al contenido

Map y WeakMap en JavaScript

· 5 minutos de lectura

Mapa viejo.

Usualmente cuando pienso en almacenar información en JavaScript pienso en hacerlo en objetos o en arrays. Actualmente existen otras estructuras de datos que nos permiten almacenar información en JavaScript, una de ellas es el Map y el WeakMap, que ponen en relación una clave con un valor, pero con diferencias importantes.

Map

Los objetos Map1 son como un tipo de diccionarios en donde nosotros asociamos un key o una llave con un valor. Los objetos Map se construyen utilizando el keyword new y llamando a la clase Map. Una ventaja es que con los Map podemos utilizar cualquier tipo de dato como key.

const map = new Map([["key", "value"], [1, "uno"], [true, "verdadero"]]); console.log(map.get("key")); // valueconsole.log(map.get(1)); // unoconsole.log(map.get(true)); // verdadero

Métodos

Los objetos Map tienen una serie de métodos que nos permiten interactuar con el mismo. Aquí tenemos una lista de los métodos que podemos utilizar con los objetos Map.

Set

Para asignar un key a un valor utilizamos el método set.

const map = new Map(); map.set("key", "value");map.set(1, "uno");map.set(true, "verdadero");const simpleObject = {};map.set(simpleObject, "objeto"); for ([key, value] of map) {  console.log(key, value);}

Clear

Elimina todos los valores asociados al objeto Map.

const map = new Map([["key", "value"], [1, "uno"], [true, "verdadero"]]);console.log(map.get("key")); // value map.clear();console.log(map.get("key")); // undefined

Delete

Elimina un valor asociado al objeto Map.

const map = new Map([["key", "value"], [1, "uno"], [true, "verdadero"]]);console.log(map.get("key")); // valueconsole.log(map.get(1)); // uno map.delete("key");console.log(map.get("key")); // undefinedconsole.log(map.get(1)); // uno

Has

Devuelve true si el objeto map tiene un valor asociado al key que se le pasa como parámetro. En caso contrario devuelve false.

const map = new Map();map.set(window, "hey"); map.has(window); // truemap.has("no");  // false

forEach

Permite iterar sobre los valores asociados al objeto map. El método forEach recibe una función que recibe dos parámetros: el key y el value. El método forEach no devuelve ningún valor.

const map = new Map([["key", "value"], [1, "uno"], [true, "verdadero"]]);map.forEach((value, key) => {  console.log(key, value);});

WeakMap

El objeto WeakMap2 es similar al Map, que solo aceptan objetos como key y que pueden ser recolectados por el garbage collector.

Garbage Collector

El garbage collector es un proceso que se ejecuta en el navegador que elimina los objetos que ya no están referenciados de la memoria, esto ayuda a no consumir recursos innecesarios y que no colapse la memoria.

Características de WeakMap

Son similares a los objetos Map pero con algunas diferencias esenciales:

  • Solo se pueden asociar objetos como key.

    const weakMap = new WeakMap([["key", "value"], [1, "uno"], [true, "verdadero"]]);
    1
    2
    3
    4
    Uncaught TypeError: Invalid value used as weak map key
        at WeakMap.set (<anonymous>)
        at new WeakMap (<anonymous>)
        at <anonymous>:1:17
    
  • No tiene el método keys() por lo que no podemos acceder a values(), entries(), clear() o la propiedad size WeakMap y tampoco es iterable.

  • Los objetos asociados a un objeto WeakMap será recolectado por el garbage collector cuando ya no existan más referencias a ellos.

Ya que la consola de chrome es lazy, es probable que podamos ver actuar al garbage collector con el siguiente ejemplo al ver lo que pasa al convertir el objecto a null.

let obj = {};let map = new Map([[obj, "value"]]);console.log(map.get(obj));obj = null;console.log(map); let obj2 = {};let weakMap = new WeakMap([[obj2, "value2"]]);console.log(weakMap.get(obj2));obj2 = null;console.log(weakMap);
Garbage collector en weakMap

Al convertir el objeto a null, weakMap perdio la única propiedad que tenía con referencia a ese objeto

Diferencias entre Map y Object

  • Los objetos solo permiten asociar como key los strings o symbol. Si pasamos otro valor, JavaScript hará una coerción de datos para convertir el valor en un string.
  • Podemos acceder al tamaño de un Map con el método size, algo que con los objetos no podemos hacer.
  • La forma en la que podemos iterarlos es diferente.
// Mapconst map = new Map([["key", "value"], [1, "uno"], [true, "verdadero"]]);for (let [key, value] of map) {  console.log(key, value);} // Objetosconst obj = {"key": "value", "key2": "value2"};const keys = Object.keys(obj);keys.forEach(key => {  console.log(key, obj[key]);}); // o bienfor (key in obj) {  console.log(key, obj[key])}
  • La forma de eliminar un valor de un Map es mediante el método delete y con los objetos mediante el operador delete.
// Mapconst map = new Map([["key", "value"], [1, "uno"], [true, "verdadero"]]);console.log(map.size); // 3map.delete("key");console.log(map.size); // 2 // Objectconst obj = {key: "value", 1: "uno", true: "verdadero"};console.log(Object.keys(obj).length); // 3delete obj.key;console.log(Object.keys(obj).length); // 2

Precaución: El operador delete en varios escenarios puede cambiar la velocidad arbitrariamente, por lo que no es muy recomendable de usar cuando se requiere un buen rendimiento de la aplicación.

Houssein Djirdeh
Houssein Djirdeh@hdjirdeh ·

Today I learned about the delete operator in JavaScript. How have I never heard about this before? 🙃

@hdjirdeh Since we can’t explicitly call JavaScript’s garbage collector, it usually isn’t a great idea to mark objects as deleted, using the delete keyword, as only objects with no existing references to them will be cleaned. It might be more performant to use the rest operator

Ver otros tweets de Mauricio Correa

Conclusión

Las estructuras de datos Map y WeakMap son otra alternativa para almacenar datos en forma de clave-valor, que pueden servir para casos especiales, según las necesidades de nuestra aplicación. Existen también estructuras de datos Set y WeakSet que son similares a estas, por lo que le puedes echar un vistazo.

Referencias

  1. MDN Web Docs & MDN contributors Map

  2. MDN Web Docs & MDN contributors WeakMap


Recibirás actualizaciones del blog con temas de programación

Descubre más sitios indie