HTML: Markup language
CSS: Styling language
JavaScript: Scripting language
Web APIs: Programming interfaces
All web technology
Learn web development
Discover our tools
Get to know MDN better
Esta página ha sido traducida del inglés por la comunidad. Aprende más y únete a la comunidad de MDN Web Docs.
View in English Always switch to English
This feature is well established and works across many devices and browser versions. It’s been available across browsers since julio de 2015.
* Some parts of this feature may have varying levels of support.
El objeto Map retiene tuplas de llave-valor y mantiene el orden de inserción de las llaves. Cualquier valor (ambos objetos y valores primitivos) puede ser usado como llave o valor.
Map
const map1 = new Map(); map1.set("a", 1); map1.set("b", 2); map1.set("c", 3); console.log(map1.get("a")); // Expected output: 1 map1.set("a", 97); console.log(map1.get("a")); // Expected output: 97 console.log(map1.size); // Expected output: 3 map1.delete("b"); console.log(map1.size); // Expected output: 2
Los objetos Map son colecciones de tuplas tipo llave-valor. Una llave en Map puede aparecer solo una vez; es única en la colección de Map. Un objeto Map es iterado por sus tuplas llave-valor —un bucle for...of regresa un arreglo de [llave, valor] por cada iteración. La iteración sucede en orden de inserción, la cual corresponde al orden en el que cada tupla llave-valor fue incertada inicialmente en el map por el método set() (eso es, si no había una llave con el mismo valor en el map, cuando set() fué llamado).
for...of
[llave, valor]
set()
La especificación requiere que los maps sean implementados "que, en promedio, proporcione tiempos de acceso que sean sublineales al numero de elementos en la colección". Por lo tanto, podría ser representado internamente como una tabla hash (con una busqueda O(1)), un árbol de búsqueda (con una busqueda de O(log(N))), o cualquier otra estructura de datos, mientras la complejidad sea mejor que O(N).
La igualdad de valores se basa en el algoritmo Igualdad SameValueZero. (Se solía usar igualdad SameValue, el cual trataba 0 y -0 como diferentes. Revise compatibilidad con navegadores.) Lo que significa que NaN es conciderado lo mismo que NaN (a pesar de que NaN !== NaN) y todos los otros valores son conciderados iguales, de acuerdo a la semantica del operador ===.
0
-0
NaN
NaN !== NaN
===
Object es similar a Map—ambos te permiten asignar llaves a valores, recuperar esos valores, borrar llaves, y detectar si hay algo guardado en una llave. Por esta razón (y porque no había alternativas incorporadas), históricamente Object se ha usado como Map.
Object
Sin embargo, hay diferencias importantes que hacen que se prefiera a Map en algunos casos:
Un objeto Object tiene un prototipo, así que tiene llaves por defecto que podrían coincidir con tus propias llaves si no tienes cuidado.
Nota: Esto se puede evitar usando Object.create(null), pero raramente se hace.
Object.create(null)
Asignar tuplas de llave-valor proporcionadas por el usuario en un Object puede permitir a un atacante sobreescribir el prototipo del objeto, lo que puede llevar a ataques de inyección de objetos . Al igual que el problema con la colisión de llaves, esto se puede mitigar usando un objeto con prototipo-null
null
String
Symbol
Las llaves en un objeto Map son ordenadas de forma simple y directa: El objeto Map itera las entradas, llaves y valores en el orden en que fueron insertadas.
A pesar de que ahora las llaves de un objeto común Object están ordenadas, esto no siempre fué el caso, y el orden es complejo. Como resultado es mejor no confiar en el orden de las propiedades.
El orden en ECMAScript 2015 fué definido inicialmente para las propiedades propias del objeto; ECMAScript 2020 define un orden también para propiedades heredadas. Pero nótese que ningún mecanismo único itera todas las propiedades de un objeto; de los varios mecanismos, cada uno inluye un subconjunto diferente de propiedades; (for-in incluye sólo propiedades donde la llave es una cadena de texto enumerable; Object.keys incluye sólo propiedades propias, enumerables, y las llaves son cadenas de texto; Object.getOwnPropertyNames incluye propias, llaves de cadena de texto incluso si no son enumerables; Object.getOwnPropertySymbols hace lo mismo sólo para propiedades que su llave es un Symbol etc.)
for-in
Object.keys
Object.getOwnPropertyNames
Object.getOwnPropertySymbols
size
Objeto
length
Object.keys()
Object no implementa un protocolo de iteración, por eso los objetos no son directamente iterables usando la sentencia de JavaScript for...of (por defecto).
Nota:
Object.entries
Se desempeña mejor en escenarios que involucran adiciones y eliminaciones frecuentes de tuplas llave-valor.
No está optimizado para adiciones y eliminaciones frequentes de tuplas llave-valor.
No tiene soporte nativo para serialización o análisis de cadenas de texto.
(Pero puedes construir tu propio soporte para serialización y análisis de cadenas de texto para Map utilizando JSON.stringify() con su argumento replacer, y utilizando JSON.parse() con su argumento reviver. Mirese la pregunta de Stack Overflow How do you JSON.stringify an ES6 Map?).
JSON.stringify()
JSON.parse()
Tiene soporte nativo para serialización de Object a JSON, usando JSON.stringify().
Tiene soporte nativo para análisis de cadenas de JSON a Object, usando JSON.parse().
Asignar propiedades de objeto funciona también para objetos Map, y puede crear confusión.
Por lo tanto, de alguna manera esto parece funcionar:
const wrongMap = new Map(); wrongMap["bla"] = "blaa"; wrongMap["bla2"] = "blaaa2"; console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
Pero esta manera de asignar una propiedad, no interactua con la estructura de datos del objeto Map. Utiliza la característica de el objeto genérico. El valor 'bla' no es guardado en el Map para consultas. Otras operaciones que fallan:
wrongMap.has("bla"); // false wrongMap.delete("bla"); // false console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
El uso correcto para guardar datos en el objeto Map es através de el método set(key, value).
set(key, value)
const contacts = new Map(); contacts.set("Jessie", { telefono: "213-555-1234", direccion: "123 N 1st Ave", }); contacts.has("Jessie"); // true contacts.get("Hilary"); // undefined contacts.set("Hilary", { telefono: "617-555-4321", direccion: "321 S 2nd St" }); contacts.get("Jessie"); // {teléfono: "213-555-1234", dirección: "123 N 1st Ave"} contacts.delete("Raymond"); // false contacts.delete("Jessie"); // true console.log(contacts.size); // 1
Objetos del Navegador similares a Map (o "objetos que parecen map") son interfaces de la API Web que se comportan en muchos aspectos como un objeto Map.
Al igual que el objeto Map, las entradas pueden iterarse en el mismo orden en que fueron agregadas al objeto. Los objetos similares a Map y los objetos Map también tienen propiedades y métodos que comparten el mismo nombre y comportamiento. Sin embargo, contrario a los objetos Map estos sólo permiten tipos específicos predefinidos para las llaves y valores de cada entrada.
Los tipos permitidos se encuentran en la especificación de la definición IDL (Interfaz de Descripcion del Lenguage). Por ejemplo, RTCStatsReport es un objeto similar a Map que debe usar cadenas de caracteres para sus llaves, y objetos para sus valores. Esto está definido en la especificación IDL a continuación:
RTCStatsReport
interface RTCStatsReport { readonly maplike<DOMString, object>; };
Los objetos similares a Map son o de solo-lectura o lectura-escritura (véase la palabra clave readonly en el IDL de arriba).
readonly
entries()
forEach()
get()
has()
keys()
values()
[Symbol.iterator]()
clear()
delete()
Los métodos y propiedades tienen el mismo comportamiento que las entidades equivalentes en el objeto Map, excepto por la restricción en los tipos de llaves y valores.
Los siguientes, son ejemplos de objetos de navegador similares a Map:
AudioParamMap
EventCounts
KeyboardLayoutMap
MIDIInputMap
MIDIOutputMap
Map()
Crea un nuevo objeto Map.
Map[Symbol.species]
La función constructor que es usada para crear objetos derivados.
Map.groupBy()
Agrupa los elementos de un iterable usando los valores que regresa la función provista. El objeto Map que regresa, usa como llaves los valores únicos de la función de prueba, los cuales pueden ser usados para obtener el arreglo de elementos de cada grupo.
Estas propiedades están definidas en Map.prototype y las comparten todas las instancias de Map.
Map.prototype
Map.prototype.constructor
La funcion constructor que creó el objeto de instancia. Para las instancias de Map el valor inicial es el constructor Map.
Map.prototype.size
Regresa el número de tuplas llave/valor en el objeto Map.
Map.prototype[Symbol.toStringTag]
El valor inicial de la propiedad [Symbol.toStringTag] es la cadena de caracteres "Map". Esta propiedad es usada en Object.prototype.toString().
[Symbol.toStringTag]
"Map"
Object.prototype.toString()
Map.prototype.clear()
Remueve todas las tuplas llave-valor del objeto Map.
Map.prototype.delete()
Regresa true si un elemento en el objeto Map existía y ha sido removido, or false si el elemento no existe.map.has(key) regresará false después de esto.
true
false
map.has(key)
Map.prototype.entries()
Regresa un nuevo objeto Iterador que contiene un arreglo con dos miembros [llave, valor] por cada elemento en el objeto Map en orden de inserción.
Map.prototype.forEach()
Llama una función callbackFn una vez por cada tupla llave-valor presente en el objeto Map, en orden de inserción. Si un parametro thisArg es proporcionado a forEach, será utilizado como el valor this para cada llamada a la funcion callback.
callbackFn
thisArg
forEach
this
Map.prototype.get()
Regresa el valor asociado a la llave que se pasa como argumento, o undefined si no hay ninguno.
undefined
Map.prototype.has()
Regresa un booleano indicando si, en el objeto Map un valor ha sido asociado a la llave pasada como argumento.
Map.prototype.keys()
Regresa un nuevo objeto Iterador que contiene las llaves para cada elemento en el objeto Map, en orden de inserción.
Map.prototype.set()
Asigna el valor en el objeto Map para la llave pasada como argumento. Regresa el objeto Map.
Map.prototype.values()
Regresa un nuevo objeto Iterador que contiene los valores para cada elemento en un objeto Map, en orden de inserción.
Map.prototype[Symbol.iterator]()
Regresa un nuevo objeto Iterador que contiene un arreglo con dos miembros [llave, valor] por cada elemento en el objeto Map, en orden de inserción.
const myMap = new Map(); const keyString = "a string"; const keyObj = {}; const keyFunc = function () {}; // asignando valores myMap.set(keyString, "valor asociado con la llave 'a string'"); myMap.set(keyObj, "valor asociado con la llave keyObj"); myMap.set(keyFunc, "valor asociado con la llave keyFunc"); console.log(myMap.size); // 3 // obteniendo los valores console.log(myMap.get(keyString)); // "valor asociado con la llave 'a string'" console.log(myMap.get(keyObj)); // "valor asociado con la llave keyObj" console.log(myMap.get(keyFunc)); // "valor asociado con la llave keyFunc" console.log(myMap.get("a string")); // "valor asociado con la llave 'a string'", porque keyString === 'a string' console.log(myMap.get({})); // undefined, porque keyObj !== {} console.log(myMap.get(function () {})); // undefined, porque keyFunc !== function () {}
NaN puede también usarse como una llave. A pesar que cada NaN no es igual a si mismo (NaN !== NaN es verdadero), el siguiente ejemplo funciona porque los NaN son indistinguibles entre sí:
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"
Los Maps pueden iterarse usando un bucle for...of:
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 = one 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
Los Maps pueden iterarse usando el método forEach():
myMap.forEach((value, key) => { console.log(`${key} = ${value}`); }); // 0 = zero // 1 = one
const kvArray = [ ["key1", "value1"], ["key2", "value2"], ]; // Usa el constructor ordinario Map para transformar un Array 2D llave-valor a un map const myMap = new Map(kvArray); console.log(myMap.get("key1")); // "value1" // Usa Array.from() para transformar un map a un Array 2D llave-valor console.log(Array.from(myMap)); // Mostrará exactamente el mismo Array como kvArray // Una forma concisa de hacer lo mismo, usando la sintaxis spread console.log([...myMap]); // O usa los iteradores keys() o values(), y conviertelos a un arreglo console.log(Array.from(myMap.keys())); // ["key1", "key2"]
Así como los Array, los Map pueden clonarse:
Array
const original = new Map([[1, "one"]]); const clone = new Map(original); console.log(clone.get(1)); // one console.log(original === clone); // false (útil para comparaciones superficiales)
Nota: Tenga en cuenta que los datos en si no se clonan.
Los objetos Map pueden unirse, manteniendo la unicidad de las llaves:
const first = new Map([ [1, "one"], [2, "two"], [3, "three"], ]); const second = new Map([ [1, "uno"], [2, "dos"], ]); // Al unir ambos maps. La ultima llave repetida gana. // la sintaxis Spread convierte un Map a un 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
Los Maps también pueden unirse a Arrays:
const first = new Map([ [1, "one"], [2, "two"], [3, "three"], ]); const second = new Map([ [1, "uno"], [2, "dos"], ]); // Merge maps with an array. The last repeated key wins. 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
Enable JavaScript to view this browser compatibility table.
core-js
Set
WeakMap
WeakSet