Objeto Map em JavaScript: introdução, métodos e exemplos

Objeto Map em JavaScript: introdução, métodos e exemplos

Map é um construtor que oferece formas mais simples e mais eficazes de estruturar dados e de lhes aceder em certos casos de uso. 

Em três pontos, eis o que um objeto Map faz de concreto:

  • Um Map contém pares chave-valor em que as chaves podem ser de qualquer tipo de dados.

  • Um Map guarda a ordem de inserção original das chaves.

  • Um Map tem uma propriedade que representa o seu tamanho.

Métodos úteis do objeto Map em JavaScript

  • clear() – remove todos os elementos do objeto map.
  •  delete(key) – remove o elemento indicado pela chave. Devolve true se o elemento existia no objeto Map, e false caso contrário.
  •  entries() – devolve um novo objeto Iterator que contém um array [key, value] por cada elemento do objeto map. A ordem dos elementos no objeto Map é a ordem de inserção.
  •  forEach(callback[, thisArg]) – invoca um callback para cada par chave-valor do Map, pela ordem de inserção. O parâmetro opcional thisArg define o valor de this em cada callback.
  •  get(key) – devolve o valor associado à chave. Se a chave não existir, devolve undefined.
  •  has(key) – devolve true se existir um valor associado à chave, e false caso contrário.
  •  keys() –  devolve um novo Iterator com as chaves dos elementos pela ordem de inserção.
  •  set(key, value) – define o valor da chave no objeto map. Devolve o próprio objeto map, por isso podes encadear este método com outros.
  •  values() devolve um novo objeto iterador com os valores de cada elemento pela ordem de inserção.

Exemplos de utilização do objeto Map em JavaScript

Criar um novo objeto Map

Imagina que tens uma lista de objetos de utilizador como esta:

javascript
let pierre = {name: 'Pierre Lepez'},
    jean = {name: 'Jean Doe'},
    kevin = {name: 'Kévin Gomez'};

Suponhamos que precisas de criar um objeto Map com os utilizadores e os respetivos papéis. Nesse caso, escreves o código seguinte:

javascript
let userRoles = new Map();

O userRoles é uma instância do objeto Map e o seu tipo é um objeto, como mostra o exemplo seguinte:

javascript
console.log(typeof(userRoles)); // object
console.log(userRoles instanceof Map); // true

Acrescentar elementos a um Map

Para atribuir um papel a um utilizador, usas o método set():

javascript
userRoles.set(kevin, 'admin');

O método set() associa o utilizador kevin ao papel de administrador. Como o set() é encadeável, podes poupar algumas linhas, como mostra este exemplo:

javascript
userRoles.set(pierre, 'éditeur')
          .set(jean, 'abonné');

Inicializar um objeto Map com um iterável

Como já foi dito, podes passar um objeto iterável ao construtor Map():

javascript
let userRoles = new Map([
    [kevin, 'admin'],
    [pierre, 'éditeur'],
    [jean, 'abonné']
]);

Obter um elemento pela chave

Se quiseres ver os papéis do Kévin, usas o método get():

javascript
userRoles.get(kevin); // admin

Se passares uma chave que não existe, o método get() devolve undefined.

javascript
let foo = {name: 'Foo'};
userRoles.get(foo); //undefined

Verificar a existência de um elemento pela chave

Para saber se uma chave existe no nosso objeto Map, usas o método has().

javascript
userRoles.has(foo); // false
userRoles.has(pierre); // true

Obter o número de elementos do nosso objeto Map

A propriedade size devolve o número de entradas do objeto Map.

javascript
console.log(userRoles.size); // 3

Iterar sobre as chaves do teu objeto Map

Para obteres as chaves de um objeto Map, usas o método keys(). O método keys() devolve um novo objeto iterador com as chaves dos elementos do objeto.

O exemplo seguinte mostra o nome dos utilizadores presentes no objeto map userRoles.

javascript
let kevin = { name: 'Kévin Feige' },
  pierre = { name: 'Pierre Rocher' },
  jean = { name: 'Jean Moulin' };

let userRoles = new Map([
    [kevin, 'admin'],
    [pierre, 'éditeur'],
    [jean, 'abonné']
]);

for (const user of userRoles.keys()) {
  console.log(user.name);
}

Resultado:

javascript
Kévin Feige
Pierre Rocher
Jean Moulin

Iterar sobre os valores do teu objeto Map

Da mesma forma, podes usar o método values() para obteres um objeto iterador com os valores de todos os elementos do teu objeto Map:

javascript
let kevin = { name: 'Kévin Feige' },
  pierre = { name: 'Pierre Rocher' },
  jean = { name: 'Jean Moulin' };

let userRoles = new Map([
    [kevin, 'admin'],
    [pierre, 'éditeur'],
    [jean, 'abonné']
]);

for (const role of userRoles.values()) {
  console.log(role);
}

Resultado:

javascript
admin
éditeur
abonné

Iterar sobre os elementos do teu objeto Map

Já o método entries() devolve um objeto iterador com um array [key,value] por cada elemento do objeto Map:

javascript
let kevin = { name: 'Kévin Feige' },
  pierre = { name: 'Pierre Rocher' },
  jean = { name: 'Jean Moulin' };

let userRoles = new Map([
    [kevin, 'admin'],
    [pierre, 'éditeur'],
    [jean, 'abonné']
]);

for (const role of userRoles.entries()) {
  console.log(`${role[0].name}: ${role[1]}`);
}

Para tornar a iteração mais natural, podes usar a desestruturação:

javascript
let kevin = { name: 'Kévin Feige' },
  pierre = { name: 'Pierre Rocher' },
  jean = { name: 'Jean Moulin' };

let userRoles = new Map([
    [kevin, 'admin'],
    [pierre, 'éditeur'],
    [jean, 'abonné']
]);

userRoles.forEach((role, user) => console.log(`${user.name}: ${role}`));

Além do ciclo for…of, podes usar o método forEach() do objeto map:

Converter as chaves ou os valores do Map num array

Às vezes queres trabalhar com um array em vez de um objeto iterável, nesse caso, podes usar o operador de propagação ( spread operator ).

O exemplo seguinte converte as chaves de cada elemento num array de chaves:

javascript
var keys = [...userRoles.keys()];
console.log(keys);

Resultado:

javascript
[ { name: 'Kévin Feige' },
  { name: 'Pierre Rocher' },
  { name: 'Jean Moulin' } ]

E este converte os valores dos elementos num array:

javascript
let roles = [...userRoles.values()];
console.log(roles);

Resultado:

javascript
[ 'admin', 'éditeur', 'abonné' ]

Apagar um elemento pela sua chave

Para apagares uma entrada do teu objeto Map, usas o método delete().

javascript
userRoles.delete(pierre);

Apagar todos os elementos de um objeto Map

Para apagares todas as entradas do objeto Map, usas o método clear():

javascript
userRoles.clear();
console.log(userRoles.size); // 0

WeakMap

Um WeakMap é parecido com um Map, com a diferença de que as chaves de um WeakMap têm de ser objetos. Isso significa que, quando a referência a uma chave (um objeto) sai de âmbito, o valor correspondente é automaticamente libertado da memória.

Um WeakMap só tem os métodos de um subconjunto do objeto Map:

  • get(key)
  • set(key, value)
  • has(key)
  • delete(key)

Eis as principais diferenças entre um Map e um WeakMap:

  • Os elementos de um WeakMap não podem ser iterados.
  • Não é possível apagar todos os elementos de uma só vez.
  • Não é possível saber o tamanho de um WeakMap.

Neste tutorial aprendeste a trabalhar com o objeto Map do JavaScript e com os seus métodos úteis para manipular as entradas do objeto Map.

JavaScript

Damien Flandrin Programador web desde 2010, criador da Gekkode e do Email Impact. Cada artigo é testado num projeto real antes de ser publicado. Contacto
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.