WeakMap - JavaScript

WeakMap representa uma evolução da coleção Map. A característica distintiva do WeakMap é que todos os seus elementos devem ser objetos, e os mesmos requisitos se aplicam às chaves.

Criação de um WeakMap:

// WeakMap vazio
const weakMap1 = new WeakMap();
    
// WeakMap com dados inicializados
let key1 = {key:1};
let key2 = {key:2};
let value1 = {name: "Tom"};
let value2 = {name: "Sam"};
    
const weakMap2 = new WeakMap([[key1, value1], [key2, value2]]);

É importante notar que um objeto WeakMap não suporta iteração.

Para adicionar um par chave-valor ao WeakMap, utiliza-se o método set():

let key1 = {key:1};
let key2 = {key:2};
let value1 = {name: "Tom"};
let value2 = {name: "Sam"};
 
const weakMap2 = new WeakMap([[key1, value1]]);
weakMap2.set(key2, value2);
weakMap2.set(key1, {name: "Kate"});
console.log(weakMap2.get(key1));    // {name: "Kate"}
console.log(weakMap2.get(key2));    // {name: "Sam"}

Para recuperar objetos por chave no WeakMap, utiliza-se o método get():

let key1 = {key:1};
let key2 = {key:2};
let value1 = {name: "Tom"};
let value2 = {name: "Sam"};
    
const weakMap2 = new WeakMap([[key1, value1], [key2, value2]]);
console.log(weakMap2.get(key1));    // {name: "Tom"}

Para verificar a presença de um elemento por uma chave específica, usa-se o método has(), que retorna true se o elemento estiver presente:

let key1 = {key:1},
    key2 = {key:2};
let value1 = {name: "Tom"},
    value2 = {name: "Sam"};
 
const weakMap2 = new WeakMap([[key1, value1]]);
console.log(weakMap2.has(key1));    // true
console.log(weakMap2.has(key2));    // false

Para remover um elemento, usa-se o método delete(), passando a chave do elemento a ser removido:

let key1 = {key:1},
    key2 = {key:2};
let value1 = {name: "Tom"},
    value2 = {name: "Sam"};
 
const weakMap2 = new WeakMap([[key1, value1], [key2, value2]]);
console.log(weakMap2.has(key1));    // true
weakMap2.delete(key1);
console.log(weakMap2.has(key1));    // false

O método clear() remove todos os elementos do WeakMap:

let key1 = {key:1},
    key2 = {key:2};
let value1 = {name: "Tom"},
    value2 = {name: "Sam"};

const weakMap2 = new WeakMap([[key1, value1], [key2, value2]]);

console.log(weakMap2.has(key1));    // true
console.log(weakMap2.has(key2));    // true

weakMap2.clear();

console.log(weakMap2.has(key1));    // false
console.log(weakMap2.has(key2));    // false

Referências Fracas

Objetos são passados para WeakMap por referência. Uma característica distintiva do WeakMap é que quando um objeto deixa de existir por diversas razões, ele é automaticamente removido do WeakMap. Vamos considerar o exemplo a seguir:

let jsCode = {code: "js"},
    tsCode = {code: "ts"};
let js = {lang: "JavaScript"},
    ts = {lang: "TypeScript"};
const weakMap = new WeakMap([[jsCode, js], [tsCode, ts]]);
 
jsCode = null;
 
console.log(weakMap);
console.log("Alguma operação");
const timerId = setTimeout(function(){
    console.log(weakMap);
    clearTimeout(timerId);
}, 30000);

Inicialmente, o objeto WeakMap armazena referências a dois elementos com chaves jsCode e tsCode. Depois, a variável jsCode é configurada como null.

jsCode = null;

Isso levará à remoção do valor inicial desta variável pelo coletor de lixo do JavaScript após algum tempo.

Enquanto isso, se usarmos Map no lugar de WeakMap:

let jsCode = {code: "js"},
    tsCode = {code: "ts"};
let js = {lang: "JavaScript"},
    ts = {lang: "TypeScript"};
const map = new Map([[jsCode, js], [tsCode, ts]]);
 
jsCode = null;
 
console.log(map);   // Map(2) {{code: "js"} => {lang: "JavaScript"}, {code: "ts"} => {lang: "TypeScript"} }
console.log("Alguma operação");
const timerId = setTimeout(function(){
    console.log(map);   // Map(2) {{code: "js"} => {lang: "JavaScript"}, {code: "ts"} => {lang: "TypeScript"} }
    clearTimeout(timerId);
}, 30000);

Mesmo após algum tempo, o objeto no Map ainda estará presente, mesmo que o valor original para o qual foi configurado seja null.

Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com