--- title: Map slug: Web/JavaScript/Reference/Global_Objects/Map tags: - ECMAScript 2015 - JavaScript - Map - Reference translation_of: Web/JavaScript/Reference/Global_Objects/Map original_slug: Web/JavaScript/Reference/Objets_globaux/Map ---
L'objet Map
représente un dictionnaire, autrement dit une carte de clés/valeurs. N'importe quelle valeur valable en JavaScript (que ce soit les objets ou les valeurs de types primitifs) peut être utilisée comme clé ou comme valeur.
L'ordre d'insertion des clés est mémorisé dans l'objet et les boucles sur les Map
parcourent les clés dans cet ordre.
new Map([iterable])
itérable
[[1 , "toto"],[2, "truc"]]
). Chaque paire clé/valeur sera ajoutée au nouvel objet Map
. {{jsxref("null")}} est traité comme {{jsxref("undefined")}}.Un objet Map
permet de retrouver ses éléments dans leur ordre d'insertion. Par exemple, une boucle {{jsxref("Instructions/for...of","for...of")}} renverra un tableau de [clé, valeur]
pour chaque itération.
On notera qu'un objet Map
contenant des objets ne sera parcouru que dans l'ordre d'insertion de ces objets. Avec ES2015, l'ordre d'itération est fixé pour les objets. Toutefois, pour les versions antérieures d'ECMAScript, cet ordre n'est pas garanti.
L'égalité des clés est testée avec l'algorithme basé sur l'égalité de valeurs :
NaN
(bien que, pour l'égalité stricte NaN !== NaN
)===
).Dans les versions précédentes des brouillons ECMAScript 2015 (ES6) -0
et +0
étaient considérés différents (bien que -0 === +0
), ceci a été changé dans les versions ultérieures et a été adapté avec Gecko 29 {{geckoRelease("29")}} ({{bug("952870")}}) et une version nocturne de Chrome.
Les {{jsxref("Object", "objets","",1)}} sont similaires aux Maps
, chacun manipulant des clés associées à des valeurs, récupérant ces valeurs, supprimant des clés... Il n'y avait auparavant pas d'alternatives natives et c'est pourquoi, historiquement, les objets JavaScript ont été utilisés comme des Maps
. Malgré tout, il y a des différences importantes entre Objects
et Maps
qui permettent de distinguer une utilisation des objets Map
plus efficace :
Object
possède un prototype, certaines clés par défaut peuvent donc entrer en collision avec les clés qu'on souhaite créer. À partir d'ES5, on peut écrire map =
{{jsxref("Object.create", "Object.create(null)")}} mais cette formulation est rarement utilisée.Map
sont ordonnées tandis que les clés d'un objet n'ont pas d'ordre particulier. Ainsi, quand on parcourt une Map
, on obtient les clés selon leur ordre d'insertion. On notera qu'à partir d'ECMAScript 2015, la spécification pour les objets indique de conserver l'ordre de création pour les clés qui sont des chaînes et des symboles.Object
sont des {{jsxref("String", "chaînes de caractères","",1)}} ou des symboles (cf. {{jsxref("Symbol")}}), alors que pour une Map
ça peut être n'importe quelle valeur.Map
avec size
. En revanche, pour un Object
il faudra compter « manuellement ».Map
est un itérable et on peut donc le parcourir directement. En revanche, itérer sur un Object
nécessite de récupérer les clés de l'objet pour ensuite les parcourir.Map
permettra d'obtenir de meilleures performances si on ajoute et supprime des éléments fréquemment.Map.length
length
est 0.Map
, on utilisera plutôt {{jsxref("Map.prototype.size")}}.Map
. Permet l'addition de propriétés à tous les objets Map
.Map
Toutes les instances de Map
héritent de {{jsxref("Map.prototype")}}.
{{page('fr/docs/Web/JavaScript/Reference/Objets_globaux/Map/prototype','Propriétés')}}
{{page('fr/docs/Web/JavaScript/Reference/Objets_globaux/Map/prototype','Méthodes')}}
Map
const myMap = new Map(); const objectKey = {}, functionKey = function () {}, stringKey = "une chaîne"; // définir les valeurs myMap.set(stringKey, "valeur associée à 'une chaîne'"); myMap.set(objectKey, "valeur associée à objectKey"); myMap.set(functionKey, "valeur associée à functionKey"); myMap.size; // 3 // récupérer les valeurs myMap.get(stringKey); // "valeur associée à 'une chaîne'" myMap.get(objectKey); // "valeur associée à objetClé" myMap.get(functionKey); // "valeur associée à fonctionClé" myMap.get("une chaîne"); // "valeur associée à 'une chaîne'" // car chaineClé === 'une chaîne' myMap.get({}); // indéfini car objetClé !== {} myMap.get(function() {}); // indéfini car fonctionClé !== function () {}
NaN
comme clé{{jsxref("NaN")}} peut être utilisé comme une clé. Bien que NaN
ne soit pas strictement égal à lui-même (NaN !== NaN
est vérifié), on peut bâtir l'exemple suivant car on ne peut pas distinguer deux valeurs NaN
:
const myMap = new Map(); myMap.set(NaN, "not a number"); myMap.get(NaN); // "not a number" const otherNaN = Number("toto"); myMap.get(otherNaN); // "not a number"
Maps
avec for..of
Il est possible de parcourir les objets Map
grâce à des boucles for..of
:
const myMap = new Map(); myMap.set(0, "zéro"); myMap.set(1, "un"); for (const [key, value] of myMap) { console.log(`${key} = ${value}`); } // On aura 2 lignes : la première avec "0 = zéro" // la seconde avec "1 = un" for (const key of myMap.keys()) { console.log(key); } // On aura 2 lignes : la première avec "0" // et la seconde avec "1" for (const value of myMap.values()) { console.log(valeur); } // On aura 2 lignes : la première avec "zéro" // et la seconde avec "un" for (const [key, value] of myMap.entries()) { console.log(`${key} = ${value}`); } // On aura 2 lignes : la première avec "0 = zéro" // la seconde avec "1 = un" myMap.forEach(function(value, key) { console.log(`${key} = ${value}`); }); // On aura 2 lignes : la première avec "0 = zéro" // la seconde avec "1 = un"
Array
const keyValuePair = [["clé1", "valeur1"], ["clé2", "valeur2"]]; // On utilise le constructeur Map // pour transformer un tableau de clés/valeurs // en un objet map const myMap = new Map(keyValuePair); myMap.get("clé1"); // renvoie "valeur1" // On utilise la fonction Array.from pour transformer // une map en un tableau de clés/valeurs console.log(Array.from(myMap)); // affichera la même chose que tableauCléValeur // On peut aussi l'utiliser pour n'extraire que les clés // ou les valeurs et créer le tableau associé console.log(Array.from(myMap.keys())); // affichera ["clé1", "clé2"]
Map
Il est possible de cloner des Map
comme on clone des tableaux :
const original = new Map([ [1, 'un'] ]); const clone = new Map(original); console.log(clone.get(1)); // un console.log(original === clone); // false. Utile pour une comparaison superficielle
Attention, la donnée contenue dans la Map
n'est pas clonée.
Il est également possible de fusionner deux Map
en conservant le critère d'unicité sur les clés :
const first = new Map([ [1, 'un'], [2, 'deux'], [3, 'trois'], ]); const second = new Map([ [1, 'uno'], [2, 'dos'] ]); // On fusionne les deux maps. C'est la "dernière" version // de la clé qui l'emporte. // L'opérateur de décomposition nous permet principalement ici // de convertir une map en un tableau const fusion = new Map([...first, ...second]); console.log(fusion.get(1)); // uno console.log(fusion.get(2)); // dos console.log(fusion.get(3)); // trois
Il est également possible de fusionner des objets Map
avec des objets Array
:
const first = new Map([ [1, 'un'], [2, 'deux'], [3, 'trois'], ]); const second = new Map([ [1, 'uno'], [2, 'dos'] ]); // On peut fusionner des Maps avec un tableau // Là encore c'est le dernier exemplaire de la clé qui l'emporte const fusion = new Map([...first, ...second, [1, 'eins']]); console.log(fusion.get(1)); // eins console.log(fusion.get(2)); // dos console.log(fusion.get(3)); // trois
Spécification | État | Commentaires |
---|---|---|
{{SpecName('ES2015', '#sec-map-objects', 'Map')}} | {{Spec2('ES2015')}} | Définition initiale. |
{{SpecName('ESDraft', '#sec-map-objects', 'Map')}} | {{Spec2('ESDraft')}} |
{{Compat("javascript.builtins.Map")}}