O que são sets em JavaScript e como eles diferem dos WeakSets?
Em JavaScript,
Set é um objeto embutido para gerenciar coleções de dados. Ele permite armazenar valores únicos de qualquer tipo, sejam primitivos ou referências a objetos. Set garante que cada valor nele apareça apenas uma vez, tornando-o útil para eliminar duplicatas de um array ou lidar com coleções de valores distintos.
Quanto ao WeakSet, ele é um tipo especial de Set com menos recursos que permite armazenar referências a objetos e símbolos mantidos de forma fraca. Diferente do Set, WeakSet não suporta primitivos como números ou strings.
Diferente de um Set comum, um WeakSet armazena apenas objetos, e as referências a esses objetos são "fracas", o que significa que WeakSets não impedem que os objetos armazenados sejam coletados pelo garbage collector se não houver outras referências a eles. Em termos mais simples, se o objeto não estiver sendo usado em nenhuma outra parte do seu código, ele é removido automaticamente para liberar memória.
Para criar um Set, você usa o construtor Set e o atribui a uma variável:
const myFirstSet = new Set();
Você também pode inicializar o Set com valores:
const treeSet = new Set(["Baobab", "Jackalberry", "Mopane Tree", "Breadfruit"]);
Se você registrar o Set no console, a saída será assim:
/*
Set(4) {"Baobab", "Jackalberry", "Mopane Tree", "Breadfruit"}
[[Entries]]
0: "Baobab"
value: "Baobab"
1: "Jackalberry"
value: "Jackalberry"
2: "Mopane Tree"
value: "Mopane Tree"
3: "Breadfruit"
value: "Breadfruit"
size: 4
[[Prototype]]: Set
*/
Se você não inicializou o Set com valores, pode usar o método add() para adicionar um item ao Set:
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
O resultado e a aparência no console permanecem os mesmos.
Não esqueça que itens duplicados serão ignorados no Set:
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.add("Baobab"); //duplicate item will be ignored
console.log(treeSet);
// Set(4) {"Baobab", "Jackalberry", "Mopane Tree", "Breadfruit"}
Os outros métodos que você pode usar para manipular um Set são:
delete()clear()has()entries()forEach()keys()values()
delete() remove um item especificado do Set:
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log(treeSet); // Set(3) {"Baobab", "Jackalberry", "Mopane Tree"}
has() verifica se um valor especificado existe no Set:
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log(treeSet.has("Breadfruit")); // false
entries() retorna um iterador Set contendo um array dos valores em formato [value, value]:
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log(treeSet.entries());
// SetIterator {"Baobab" => "Baobab", "Jackalberry" => "Jackalberry", "Mopane Tree" => "Mopane Tree"}
keys() e values() mostram os valores no Set. keys() é apenas um alias para o método values():
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log("Keys: ", treeSet.keys());
console.log("Values: ", treeSet.values());
// Keys: SetIterator {"Baobab", "Jackalberry", "Mopane Tree"}
// Values: SetIterator {"Baobab", "Jackalberry", "Mopane Tree"}
forEach() permite iterar através do Set:
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
treeSet.forEach((tree) => console.log(tree));
/*
Baobab
Jackalberry
Mopane Tree
*/
clear() remove todos os itens do array:
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
treeSet.clear();
console.log(treeSet); // Set(0) {size: 0}
Também vale mencionar que existe uma propriedade size que retorna o número de itens no Set:
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log(treeSet.size); // 3
Assim como Set, também existe um construtor WeakSet que você pode usar para criar um WeakSet:
const treeWeakSet = new WeakSet();
WeakSet também possui os métodos add(), delete() e has():
const treeWeakSet = new WeakSet();
const baobab = { name: "Baobab" };
const jackalberry = { name: "Jackalberry" };
const mopaneTree = { name: "Mopane Tree" };
const breadfruit = { name: "Breadfruit" };
treeWeakSet.add(baobab);
treeWeakSet.add(jackalberry);
treeWeakSet.add(mopaneTree);
treeWeakSet.add(breadfruit);
treeWeakSet.delete(jackalberry);
console.log(treeWeakSet.has(jackalberry)); // false
console.log(treeWeakSet);
Na saída, o conteúdo do WeakSet aparece assim:
/*
WeakSet {{…}, {…}, {…}}
[[Entries]]
0: value: {name: "Mopane Tree"}
1: value: {name: "Baobab"}
2: value: {name: "Breadfruit"}
[[Prototype]]: WeakSet
*/
O conteúdo é visível aqui porque as variáveis dos objetos ainda mantêm referências fortes, mantendo esses objetos na memória. Lembre-se que WeakSets não são iteráveis, então não há como iterar sobre suas entradas ou acessá-las programaticamente. O que você vê na saída é apenas uma ajuda para depuração.
Não esqueça que apenas símbolos e objetos com chaves e valores bem definidos são suportados. Adicionar um primitivo, como números ou strings, resultará em um erro:
treeWeakSet.add("Alan Smith");
console.log(treeWeakSet); // Invalid value used in weak set
// at WeakSet.add (<anonymous>)
A principal diferença entre um Set e um WeakSet é que um Set armazena qualquer valor, enquanto um WeakSet pode armazenar apenas objetos.
Aqui estão algumas outras diferenças notáveis entre um Set e um WeakSet:
| Recurso | Set | WeakSet |
| --- | --- | --- |
| Tipo de valores armazenados | Armazena qualquer tipo de dado | Armazena apenas objetos |
| Referência | Referência forte | Referência fraca |
| Iteração | Suporta iteração com forEach e loops | Não suporta iteração |
| Métodos e propriedades | add(), delete(), has(), keys(), values(), size e mais | Apenas add(), delete() e has() |
| Caso de uso | Coleção geral de valores únicos e remoção de duplicatas de arrays | Rastreamento eficiente de memória para referências a objetos |
Você pode ver as diferenças nos tipos de valores que os dois tipos de sets podem armazenar, seu suporte para iterar sobre os objetos armazenados e seus casos de uso ideais. Reserve um momento para ler o conteúdo desta tabela.Este módulo não possui perguntas. Marque como concluído.