Coleções chaveadas
==================

* « Previous
* Next »

Este capítulo apresenta coleções de dados que são ordenados por uma chave; Objetos Map e Set contêm elementos que são iteráveis em ordem de inserção.

Mapas
-----

### `Objeto Map`

ECMAScript 6 apresenta uma nova estrutura de dados para mapear valores para valores. Um objeto `Map` é um simples mapa de chave/valor que pode ter seus elementos iterados por ordem de inserção.

O código a seguir mostra algumas operações básicas com um `Map`. Veja também a página de referência do `Map` para mais exemplos e a API completa. Você pode usar um laço `for...of` para retornar um array de `[chave, valor]` para cada iteração.


```js
var sayings = new Map();
sayings.set("dog", "woof");
sayings.set("cat", "meow");
sayings.set("elephant", "toot");
sayings.size; // 3
sayings.get("fox"); // undefined
sayings.has("bird"); // false
sayings.delete("dog");
sayings.has("dog"); // false

for (var [key, value] of sayings) {
  console.log(key + " goes " + value);
}
// "cat goes meow"
// "elephant goes toot"

sayings.clear();
sayings.size; // 0
```

### `Object` e `Map` comparados

Tradicionalmente, objetos tem sido usado para mapear strings para valores. Objetos permitem que você defina chaves para valores, recupere esses valores, exclua chaves e detecte se algo está armazenado em uma chave. Objetos `Map`, contudo, possuem algumas vantagens que os tornam mapas melhores.

* As chaves de um `Objeto` são `Strings`, onde elas podem ser de qualquer valor para um `Map`.
* Você pode obter o tamanho de um `Map` facilmente enquanto que para um `Object`, você tem que obter manualmente o seu tamanho.
* A iteração de mapas é por ordem de inserção dos elementos.
* Um `Object` tem um protótipo, então existem chaves padrão no mapa. (este pode ser ignorado usando `map = Object.create(null)`).

Estes dois tipos podem ajudar você a decidir se usa um `Map` ou um `Object`:

* Use mapas sobre objetos quando as chaves forem desconhecidas até a execução, e quando todas as chaves são do mesmo tipo e todos valores são do mesmo tipo.
* Use mapas caso haja a necessidade de armazenar valores primitivos como chaves, porque objetos tratam cada chave como uma string ou um valor numérico, valor booleano ou qualquer outro valor primitivo.
* Use objetos quando há uma lógica que opera em elementos individuais.
### `Objeto WeakMap`

O objeto `WeakMap` é uma coleção de pares de chave/valor em que as **chaves são somente objetos** e seus valores podem ser valores arbitrários. As referências do objeto nas chaves são *fracamente* mantidas, isso significa que eles são alvo da garbage collection (coleta de lixo) se não houver nenhuma outra referência para o objeto. A API `WeakMap` é a mesma API do `Map`.

Uma diferença para objetos `Map` é que chaves `WeakMap` não são enumeráveis (isto é, não há um método que dê a você uma lista de chaves). Se eles fossem, a lista dependeria do estado da coleta de lixo, introduzindo um não-determinismo.

Para mais informações e código de exemplo, veja também "Por quê WeakMap?" na página de referência `WeakMap`.

Um caso de uso de objetos `WeakMap` é armazenar dados privados para um objeto ou ocultar detalhes de implementação. O exemplo a seguir é Nick Fitzgerald a partir de um post "Ocultando detalhes de implementação com WeakMaps ECMAScript 6" em seu blog. Os dados privados e métodos pertencem ao objeto e são armazenados nos objetos WeakMap `privados`. Tudo exposto na instância e o protótipo é público, todo o restante é inacessível a partir do mundo externo por que `privado` não é exportado pelo módulo.


```js
const privates = new WeakMap();

function Public() {
  const me = {
    // Dados privados vem aqui
  };
  privates.set(this, me);
}

Public.prototype.method = function () {
  const me = privates.get(this);
  // Faça coisas com dado privado em `me`...
};

module.exports = Public;
```

Conjuntos
---------

### `Objeto Set`

Objetos `Set` são coleções de valores. Você pode iterar seus elementos em ordem de inserção. Um valor em um `Set` só pode ocorrer uma vez; ele é único em uma coleção `Set`.

O código a seguir mostra algumas operações básicas com um `Set`. Veja também a página de referência `Set` para mais exemplos e a API completa.


```js
var mySet = new Set();
mySet.add(1);
mySet.add("some text");
mySet.add("foo");

mySet.has(1); // true
mySet.delete("foo");
mySet.size; // 2

for (let item of mySet) console.log(item);
// 1
// "some text"
```

### Conversão entre Array e Set

Você pode criar um `Array` a partir de um Set usando `Array.from` ou o operador de propagação (en-US). Além disso, o construtor `Set` aceita um `Array` para converter em outra direção. Observe novamente que objetos `Set` armazenam valores únicos, então quaisquer elementos duplicados de um Array são excluídos quando convertidos.


```js
Array.from(mySet);
[...mySet2];

mySet2 = new Set([1, 2, 3, 4]);
```

### `Array` e `Set` comparados

Tradicionalmente, um conjunto de elementos tem sido armazenados em arrays JavaScript em muitas situações. O novo objeto `Set`, contudo, tem algumas vantagens:

* Checar se um elemento existe em uma coleção usando `indexOf` para arrays é lento.
* Objetos `Set` permitem que você exclua elementos por seu valor. Com um array você teria que unir baseado no índice do elemento.
* O valor `NaN` não pode ser encontrado com `indexOf` no array.
* Objetos `Set` armazenam valores únicos, você não tem que manter o controle de duplicidades manualmente por você mesmo.
### `Objeto WeakSet`

Objetos `WeakSet` são coleções de objetos. Um objeto no `WeakSet` só pode ocorrer uma vez; Isto é único em coleções `WeakSet` e objetos não são enumeráveis.

As principais diferenças para objetos `Set` são:

* Em contraste com `Sets`, `WeakSets` são **apenas coleções de objetos** e não de valores arbritários de qualquer tipo.
* O `WeakSet` é *fraco*: Referências para objetos são fracamente realizadas na coleção. Se não há outra referência para um objeto armazenado no `WeakSet`, eles podem ser coletados pelo coletor de lixo. Isso significa também que não há uma lista de objetos correntes armazenados na coleção. `WeakSets` não são enumeráveis.

Os casos de uso do objeto `WeakSet` são limitados. Eles não vão desperdiçar memória para ser seguro o uso de elementos DOM como chaves e marcá-los para propósitos de controle, por exemplo.

Igualdade de chave e valor do `Map` and `Set`
---------------------------------------------

Ambos, a igualdade de chaves de objetos `Map` e a igualdade de valor de objetos `Set`, são baseados no "algoritmo mesmo valor de zero":

* Igualdade funciona como o operador de comparação de identidade `===`.
* `-0` e `+0` são considerados iguais.
* `NaN` é considerado igual a ela mesmo (contrário de `===`).
* « Previous
* Next »