Coleções com chave

Use literais de objeto para armazenar pares de chave-valor e matrizes para armazenar coleções iteráveis de valores. O ES6 também introduz estruturas de dados especializadas para se adequar a casos de uso mais granulares: Mapa para pares de chave-valor e Definir para valores individuais.

Mapa

Map é uma estrutura de dados iterável que armazena informações como pares de chave-valor, de maneira semelhante a um literal de objeto. Ao contrário dos literais de objeto, um Map permite que valores e chaves tenham qualquer tipo de dados. Além disso, os elementos de ordem que são adicionados a um Map são preservados durante a iteração sobre ele.

Para criar um mapa, use o construtor Map():

const myMap = new Map();

myMap;
> Map(0)

É possível pré-preencher um mapa com dados usando uma sintaxe que se assemelha a uma matriz (ou qualquer objeto iterador) contendo objetos semelhantes a matrizes compostos de dois elementos. O primeiro elemento em cada uma dessas estruturas de dados de dois elementos se torna a chave, enquanto o segundo se torna o valor associado a essa chave. A forma mais simples é uma matriz em que cada elemento é uma matriz composta por dois elementos, a chave e o valor do elemento a ser adicionado ao mapa:

const myMap = new Map([
    [ "myKey", "A string value" ],
    [ "mySecondKey", 500 ],
    [ "myThirdKey", true ]
]);

myMap;
> Map(3) {'myKey' => 'A string value', 'mySecondKey' => 500, 'myThirdKey' => true}

Novamente, um objeto Map é diferente de um literal de objeto, porque tanto os valores quanto as chaves podem assumir qualquer tipo e valor de dados:

const notAFunction = () => console.log( "function" );
const myMap = new Map([
  [ null, 0 ],
  [ false, "This is false" ],
  [ undefined, "No defined value" ],
  [ NaN, "Not a number" ]
]);

myMap;
> Map(4) {null => 0, false => 'This is false', undefined => 'No defined value', NaN => 'Not a number'}

Para receber, definir ou excluir elementos Map, use os métodos herdados do construtor Map:

const myMap = new Map();

myMap;
> Map(0)

myMap.set( "myKey", "My value." );

myMap.has( "myKey" );
> true

myMap.get( "myKey" );
"My value."

myMap.delete( "myKey" );

myMap;
> Map(0)

As chaves em um mapa são exclusivas, o que significa que definir uma chave idêntica substitui o par de chave-valor armazenado anteriormente:

const myMap = new Map([ [ "myKey", "A string value" ] ]);

myMap.set( "myKey", 500 );

myMap;
> Map(1) {'myKey' => 500}

Assim como nos objetos, você pode atribuir um mapa a uma variável declarada com const e, em seguida, modificar esse mapa. No entanto, assim como em outros casos de uso de const, não é possível alterar ou excluir a variável em si:

const myMap = new Map();
myMap.set( "myKey", "A string value" );

myMap;
> Map(1) {'myKey' => 500}

WeakMap

Um WeakMap é um mapa que contém references "fracas", que precisam ser referências a objetos ou Symbols que não foram adicionados ao registro de símbolo global.

Para criar um WeakMap, use o construtor WeakMap():

const myWeakMap = new WeakMap();

myWeakMap;
> WeakMap(0)

A sintaxe do WeakMap é semelhante à do Map, mas o WeakMaps não é iterável. Tentar usar qualquer valor diferente de um objeto ou símbolo como uma chave causa um erro de sintaxe. Quando não há references a uma chave fora do WeakMap, esse objeto ou símbolo e o valor associado no WeakMap são qualificados para a coleta de lixo.

Isso permite casos de uso como armazenamento de metadados associados a um objeto em um WeakMap, usando a referência ao objeto como a chave. Se não houver outras referências a esse objeto e ele for removido da memória, os metadados associados também serão removidos.

Definir

Um conjunto é uma coleção iterável de valores exclusivos semelhante a uma matriz, mas só pode conter valores exclusivos. Assim como em um mapa, a iteração em um conjunto preserva os elementos de ordem que foram adicionados a ele.

Para criar um conjunto, use o construtor Set():

const mySet = new Set();

mySet;
> Set []

Você também pode criar um conjunto com base em um literal de matriz:

const mySet = new Set([ 1, 2, 3 ]);

mySet;
> Set(3) [ 1, 2, 3 ]

Como um conjunto não permite elementos duplicados, quando ele é criado usando uma matriz que contém várias instâncias do mesmo valor, ele retém apenas a primeira instância desse valor:

const mySet = new Set([ 1, 2, 3, 2 ]);

mySet;
> Set(3) [ 1, 2, 3 ]

Para adicionar ou remover elementos de um conjunto, use os métodos herdados do construtor Set. Esses métodos atuam em um elemento com base no valor dele, em vez de referenciar um índice:

const mySet = new Set();

mySet.add( "My value." );

mySet;
> Set [ "My value." ]

mySet.has( "My value." );
> true

mySet.delete( "My value." );

mySet;
> Set []

Embora os conjuntos não sejam coleções indexadas e não se destinam ao uso dessa forma, os elementos em um conjunto são iterados na ordem de inserção. As tentativas de adicionar um valor de elemento duplicado a um conjunto são ignoradas, preservando o pedido de inserção original:

const mySet = new Set([ 1, 2, 3 ]);

mySet;
> Set(3) [ 1, 2, 3 ]

mySet.add( 2 );
> Set(3) [ 1, 2, 3 ]

Para criar uma matriz com base em um conjunto, use o método Array.from() ou a sintaxe de distribuição:

const mySet = new Set([ 1, 2, 3 ]);
const myArray = Array.from( mySet );

myArray;
> Array(3) [ 1, 2, 3 ]

[ ...mySet ];
> Array(3) [ 1, 2, 3 ]

WeakSet

WeakSet é um conjunto que contém apenas valores que podem ser coletados por lixo, como referências a objetos ou Symbols que não foram adicionados ao registro global Symbol.

Para criar um WeakSet, use o construtor WeakSet():

const myWeakSet = new WeakSet();

myWeakSet;
> WeakSet []

A sintaxe de WeakSet é semelhante a Set, embora um WeakSet não seja iterável, e tentar adicionar qualquer valor que não seja um objeto ou símbolo causa um erro de sintaxe. Assim como no caso do WeakMap, quando nenhuma outra references a um valor referenciado por um WeakSet existir, esse valor se tornará qualificado para a coleta de lixo.

Isso permite casos de uso como agregar uma única coleção iterável de objetos relacionados. Se não houver outras referências a um objeto referenciado pelo WeakSet, o elemento associado também será removido do WeakSet.

Teste seu conhecimento

Considere o seguinte:

        const myMap = new Map([ [ "myKey", "My string" ] ]);
        myMap.set( "myKey", 100 );
      

O que myMap retorna?

100
"My string"
undefined