Entenda o que são WeakMap e WeakSet e como utilizá-los no JavaScript

WeakMap e WeakSet são estruturas de dados que ajudam na otimização do uso de memória. Descubra como utilizá-las em JavaScript para melhorar a performance.

O que são WeakMap e WeakSet e quando utilizá-los?

No JavaScript, o WeakMap e o WeakSet são estruturas de dados que oferecem uma maneira mais eficiente de lidar com o armazenamento de dados, especialmente quando se trabalha com objetos e a necessidade de liberar memória automaticamente.

Essas estruturas são chamadas de 'weak' (fracas) porque os dados armazenados nela são garbage collected quando não houver mais referências para os objetos armazenados. Vamos explorar como esses dois tipos de dados funcionam e como você pode utilizá-los em seu código.

O que é o WeakMap?

Um WeakMap é um tipo de coleção onde as chaves são objetos e os valores podem ser qualquer tipo de dado. A principal diferença entre um Map e um WeakMap é que, no WeakMap, as chaves são mantidas de forma fraca, ou seja, quando o objeto utilizado como chave não tem mais referências, ele é automaticamente garbage collected. Isso significa que você pode usar objetos temporários como chaves sem se preocupar com vazamentos de memória.

Exemplo de uso de WeakMap:

let objeto = { nome: 'Objeto' };
let weakmap = new WeakMap();

// Armazenando o objeto no WeakMap
weakmap.set(objeto, 'valor associado');

console.log(weakmap.get(objeto)); // 'valor associado'

O que o código está fazendo: O WeakMap armazena um objeto como chave e um valor associado a ele. Quando o objeto não for mais referenciado em outro lugar, o JavaScript pode coletar a chave automaticamente, liberando a memória sem precisar de intervenção manual.

O que é o WeakSet?

Um WeakSet é semelhante ao WeakMap, mas no caso do WeakSet, não existem valores associados. Ele simplesmente armazena objetos, e assim como no WeakMap, esses objetos são mantidos de forma fraca, o que significa que, assim que não houver mais referências ao objeto, ele será removido automaticamente do conjunto.

Exemplo de uso de WeakSet:

let objeto1 = { nome: 'Objeto 1' };
let objeto2 = { nome: 'Objeto 2' };
let weakset = new WeakSet();

// Adicionando objetos ao WeakSet
weakset.add(objeto1);
weakset.add(objeto2);

console.log(weakset.has(objeto1)); // true
console.log(weakset.has(objeto2)); // true

O que o código está fazendo: O WeakSet armazena os objetos objeto1 e objeto2. A função has verifica se o objeto existe no conjunto. Se não houver mais referências ao objeto, ele será removido automaticamente da coleção.

Quando utilizar WeakMap e WeakSet?

Você pode usar WeakMap e WeakSet para evitar vazamentos de memória em seu código, principalmente quando está lidando com objetos que podem ser removidos ou substituídos de maneira dinâmica.

Casos de uso do WeakMap:

  • Armazenamento de metadados: Quando você precisa associar dados extras a objetos sem alterar o objeto original, mas quer garantir que os dados sejam removidos automaticamente quando o objeto for destruído.
  • Caches temporários: Para evitar armazenar dados em memória de maneira permanente, você pode usar WeakMap para manter dados temporários que devem ser limpos quando o objeto associado for removido.

Casos de uso do WeakSet:

  • Referências fracas: Quando você precisa de um conjunto de objetos, mas não se importa com a manutenção de referências fortes a esses objetos. Ideal para verificar se um objeto está presente sem impedir que o coletor de lixo remova o objeto quando ele não for mais necessário.

Benefícios do WeakMap e WeakSet

  • Eficiência na memória: Ambas as estruturas ajudam a reduzir o uso de memória, pois permitem que os objetos sejam removidos automaticamente quando não houver mais referências a eles.
  • Evita vazamentos de memória: Ao usar essas coleções, você pode evitar vazamentos de memória, pois o coletor de lixo do JavaScript pode limpar os objetos quando não houver mais referências.

Diferença entre WeakMap e Map

A principal diferença entre WeakMap e Map é que, no WeakMap, as chaves são fracas, ou seja, o coletor de lixo pode remover as chaves e os valores associada a elas quando o objeto não é mais referenciado, enquanto no Map, as chaves são fortes, e elas permanecem no Map até que sejam removidas explicitamente.

Exemplo comparando WeakMap e Map:

let map = new Map();
let weakmap = new WeakMap();
let objeto1 = { nome: 'objeto1' };

map.set(objeto1, 'valor no map');
weakmap.set(objeto1, 'valor no weakmap');

console.log(map.has(objeto1)); // true
console.log(weakmap.has(objeto1)); // true

O que o código está fazendo: Aqui, comparamos a diferença entre um Map e um WeakMap. Ambos armazenam a chave objeto1, mas no caso do WeakMap, quando objeto1 não tiver mais referências, o valor será automaticamente removido do WeakMap.

Conclusão

WeakMap e WeakSet são poderosas ferramentas para otimização de memória e gerenciamento de objetos em JavaScript. Eles permitem que você trabalhe com referências fracas, fazendo com que os objetos sejam coletados automaticamente quando não forem mais necessários, evitando vazamentos de memória. Quando você precisa associar dados temporários ou manter conjuntos de objetos de maneira eficiente, essas estruturas são extremamente úteis.

O uso de WeakMap e WeakSet em JavaScript oferece uma maneira eficiente de gerenciar objetos temporários e de evitar vazamentos de memória. Com esses tipos de coleções, o coletor de lixo pode remover automaticamente objetos quando não houver mais referências a eles, garantindo que a memória seja utilizada de forma eficiente e sem desperdícios.

Algumas aplicações:

  • Uso para armazenar metadados temporários associados a objetos.
  • Manutenção de referências fracas a objetos, evitando vazamentos de memória.
  • Criação de caches temporários que são limpos automaticamente quando o objeto é removido.

Dicas para quem está começando

  • Use WeakMap quando precisar armazenar dados associados a objetos e quiser garantir que os dados sejam removidos automaticamente quando o objeto for coletado pelo lixo.
  • Evite usar Map para dados temporários se você não precisa que a chave persista enquanto o objeto estiver na memória.
  • Use WeakSet para verificar se um objeto está presente sem impedir sua remoção automática pela coleta de lixo.
  • Lembre-se de que WeakMap e WeakSet só funcionam com objetos como chaves ou elementos, e não com tipos primitivos.

Contribuições de Ricardo Vasconcellos

Compartilhe este tutorial: O que são WeakMap e WeakSet e quando utilizá-los?

Compartilhe este tutorial

Continue aprendendo:

Como evitar repinturas desnecessárias no DOM?

Repinturas desnecessárias no DOM podem prejudicar a performance de sua aplicação. Descubra como evitar esse problema e otimizar o carregamento da sua página.

Tutorial anterior

Como usar IntersectionObserver para lazy loading de imagens?

IntersectionObserver permite implementar lazy loading de imagens de maneira eficiente, otimizando a performance da sua página e reduzindo o tempo de carregamento.

Próximo tutorial