Map
O objeto Map
contém pares de chave-valor e lembra a ordem original da inserção das chaves. Qualquer valor (objetos e valores primitivos) podem ser usados como chave ou valor.
Experimente
Descrição
Um objeto Map
itera seus elementos na order da inserção - um loop for...of
retorna um array de [key, value]
para cada iteração
Igualdade de chaves
- A igualdade de chaves é baseada no algoritimo
sameValueZero
. - O
NaN
é considerado o mesmo que oNaN
(apesar deNaN !== NaN
) e todos os outros valores são considerados de acordo com a semântica do operador===
. - Na especificação atual do ECMAScript,
-0
e+0
são considerados iguais, embora não tenha sido nos esboços anteriores. Veja "Equivalência de valor entre -0 e 0" em Compatibilidade com navegadores para mais detalhes;
Objetos vs. Maps
Um Object
é similar o Map
- ambos permitem que valores sejam definidos a chaves, retornar esses valores, remover as chaves, e detectar se algo está armazenado na chave. Por esta razão (e porque não existem outras alternativas construídas), o Objeto
tem sido usado como Map
historicamente.
Porém, existem diferenças importantes que fazem o Map
ser preferido em alguns casos:
Map | Objeto | |
---|---|---|
Chaves acidentais | O Map não contém nenhuma chave por padrão. Ele só contém o que é definido explicitamente nele. |
Um Nota: Apartir do ES5, isso pode ser ignorado com o |
Tipos das chaves | As chaves do Map podem ser qualquer valor (incluindo funções, objetos, ou qualquer outro tipo primitivo). |
A chave de um Objeto deve ser uma String ou um Symbol . |
Ordem das chaves |
As chaves dentro do |
Embora as chaves de um
A ordem foi definida primeiramente para suas próprias propriedades apenas no ECMAScript 2015; no ECMAScript 2020 a ordem definida é por propriedades herdadas também.
Veja o
OrdinaryOwnPropertyKeys
e
numerateObjectProperties
operações de especificações abstraídas. Mas note que nenhum mecanismo itera todas as propriedades do objeto; cada um dos vários mecanismos incluem diferentes subconjuntos de propriedades.
( |
Tamanho |
O número de items dentro de um Map
é facilmente retornado pela propriedade size
|
O número de items dentro de um Objeto deve ser determinado manualmente |
Iteração | Um Map é iterável , então ele pode ser diretamente iterável |
O Nota:
|
Performance |
Perfoma melhor em cenários envolvendo adições e remoções frequentes em pares chave-valor. |
Não é otimizado para adições e remoções frequentes de pares chave-valor. |
Serialização e análise sintática |
Não há suporte nativo para a serialização ou análise sintática.
(Mas você pode construir sua própria serialização e conversão para o |
Suporte nativo para serialização de Suporte nativo para conversão de JSON para |
Definindo propriedades no objeto
Definir propriedades no objeto também funciona em objetos Map
, e pode causar um confusão considerável.
Portanto, isso aparenta funcionar de certa forma:
js
const wrongMap = new Map()
wrongMap['bla'] = 'blaa'
wrongMap['bla2'] = 'blaaa2'
console.log(wrongMap) // Map { bla: 'blaa', bla2: 'blaaa2' }
Mas esse jeito de definir propriedades não interage com a estrura de dados do Map
. Dessa forma é usada a implementação genérica do objeto. O valor 'bla' não é armazenado no Map
para queries. Outras operaçãoes nos dados irão falhar.
js
wrongMap.has('bla') // false
wrongMap.delete('bla') // false
console.log(wrongMap) // Map { bla: 'blaa', bla2: 'blaaa2' }
A maneira correta para armazenar dados dentro do Map
é através do set(key,value)
js
const contacts = new Map()
contacts.set('Jessie', {phone: "213-555-1234", address: "123 N 1st Ave"})
contacts.has('Jessie') // true
contacts.get('Hilary') // undefined
contacts.set('Hilary', {phone: "617-555-4321", address: "321 S 2nd St"})
contacts.get('Jessie') // {phone: "213-555-1234", address: "123 N 1st Ave"}
contacts.delete('Raymond') // false
contacts.delete('Jessie') // true
console.log(contacts.size) // 1
Construtor
Map()
-
Cria um novo objeto
Map
.
propriedades estáticas
get Map[@@species]
-
A função do construtor que é usada para criar apartir de objetos.
propriedades da instância
Map.prototype.size
-
Retorna o número de pares chave/valor no objeto
Map
.
Métodos da instância
Map.prototype.clear()
-
Remove todos os pares chave/valor do objeto
Map
. Map.prototype.delete(key)
-
Retorna
true
se o elemento no objetoMap
existia e tenha sido removido, oufalse
se o elemento não existia.Map.prototype.has(key)
irá retornarfalse
após isso. Map.prototype.get(key)
-
Retorna o valor associado à chave, ou
undefined
se não há nada. Map.prototype.has(key)
-
Retorna uma asserção booleana se o valor tenha sido associado à chave no objeto
Map
ou não. Map.prototype.set(key, value)
-
Define o
valor
para achave
no objetoMap
. Retorna o objetoMap
Métodos iterativos
Map.prototype[@@iterator]()
-
Retorna um novo objeto iterador que contèm um array de
[chave, valor]
para cada elemento do objetoMap
na ordem em que foram inseridos. Map.prototype.keys()
-
Retorna um novo objeto iterador que contèm as chaves de cada elemento do objeto
Map
na ordem em que foram inseridos. Map.prototype.values()
-
Retorna um novo objeto iterador que contém os valores para cada elemento do objeto
Map
na ordem em que foram inseridos. Map.prototype.entries()
-
Retorna um novo objeto iterador que contèm um array de
[chave, valor]
para cada elemento no objetoMap
na ordem em que foram inseridos. Map.prototype.forEach(callbackFn[, thisArg])
-
Invoca o
callbackFn
uma vez para cada par chave-valor presente no objetoMap
, na ordem em que foram inseridos. Se um parâmetrothisArg
é provido para oforEach
, será usado o valor dethis
para cada callback.
Exemplos
Usando o objeto Map
js
const myMap = new Map()
const keyString = 'a string'
const keyObj = {}
const keyFunc = function() {}
// setting the values
myMap.set(keyString, "value associated with 'a string'")
myMap.set(keyObj, 'value associated with keyObj')
myMap.set(keyFunc, 'value associated with keyFunc')
myMap.size // 3
// getting the values
myMap.get(keyString) // "valor associado a 'a string'"
myMap.get(keyObj) // "valor associado a keyObj"
myMap.get(keyFunc) // "valor associado a keyFunc"
myMap.get('a string') // "valor associado a 'a string'"
// porque keyString === 'a string'
myMap.get({}) // undefined, porque keyObj !== {}
myMap.get(function() {}) // undefined, porque keyFunc !== function () {}
Usando NaN como chaves de Map
NaN
também pode ser usado como chave. Apesar de todo o NaN
não ser igual a ele mesmo (NaN !== NaN
), o exemplo a seguir funciona porque não é possível distinguir um NaN
de outros.
js
const myMap = new Map()
myMap.set(NaN, 'not a number')
myMap.get(NaN)
// "not a number"
const otherNaN = Number('foo')
myMap.get(otherNaN)
// "not a number"
Iterando o Map com for..of
Maps
podem ser iterados usando um loop for..of
:
js
const myMap = new Map()
myMap.set(0, 'zero')
myMap.set(1, 'one')
for (const [key, value] of myMap) {
console.log(key + ' = ' + value)
}
// 0 = zero
// 1 = um
for (const key of myMap.keys()) {
console.log(key)
}
// 0
// 1
for (const value of myMap.values()) {
console.log(value)
}
// zero
// one
for (const [key, value] of myMap.entries()) {
console.log(key + ' = ' + value)
}
// 0 = zero
// 1 = one
Iterando o Map com forEach()
Maps
podem ser iterados usando o
método forEach()
:
js
myMap.forEach(function(value, key) {
console.log(key + ' = ' + value)
})
// 0 = zero
// 1 = um
Relação com Arrays
js
const kvArray = [['key1', 'value1'], ['key2', 'value2']]
// Use o construtor padrão do Map para transformar um array 2D chave-valor em um map
const myMap = new Map(kvArray)
myMap.get('key1') // retorna "value1"
// Use o Array.from() para transformar um map em um Array bidimensional de chaves e valores
console.log(Array.from(myMap)) // Irá exibir para você o mesmo Array como um Array chave-valor
// Uma forma sucinta de fazer o mesmo, utilizando a sintaxe spread
console.log([...myMap])
// Ou use os iteradores keys() ou values(), e os converta para um array
console.log(Array.from(myMap.keys())) // ["key1", "key2"]
Clonando e mesclando Maps
Assim como Arrays
, o map também pode ser clonado:
js
const original = new Map([
[1, 'um']
])
const clone = new Map(original)
console.log(clone.get(1)) // um
console.log(original === clone) // false (Útil para comparações superficiais)
Nota: Tenha em mente que o dado em si não é clonado.
Maps podem ser mesclados, mantendo as chaves únicas:
js
const first = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
])
const second = new Map([
[1, 'uno'],
[2, 'dos']
])
// Mescla dois maps. A última chave a se repetir vence.
// O operador spread essenciamente converte um Map para um Array
const merged = new Map([...first, ...second])
console.log(merged.get(1)) // uno
console.log(merged.get(2)) // dos
console.log(merged.get(3)) // three
Maps podem ser mesclados com array também:
js
const first = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
])
const second = new Map([
[1, 'uno'],
[2, 'dos']
])
// Mescla maps com um array. A última chave a se repetir vence.
const merged = new Map([...first, ...second, [1, 'eins']])
console.log(merged.get(1)) // eins
console.log(merged.get(2)) // dos
console.log(merged.get(3)) // three
Especificações
Specification |
---|
ECMAScript Language Specification # sec-map-objects |
Compatibilidade com navegadores
BCD tables only load in the browser