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.
Syntaxe
new Map([iterable])
Paramètres
Description
Un objet Map
permet de retrouver ses éléments dans leur ordre d'insertion. Par exemple, une boucle 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.
Égalité des clés
L'égalité des clés est testée avec l'algorithme basé sur l'égalité de valeurs :
NaN
est considéré égal àNaN
(bien que, pour l'égalité stricteNaN !== NaN
)- les autres valeurs sont considérées égales au sens de l'égalité stricte (l'opérateur
===
).
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 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26) (bug 952870) et une version nocturne de Chrome.
Comparaison entre objets et maps
Les objets 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 :
- Un
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 écriremap =
Object.create(null)
mais cette formulation est rarement utilisée. - Les clés d'une
Map
sont ordonnées tandis que les clés d'un objet n'ont pas d'ordre particulier. Ainsi, quand on parcourt uneMap
, 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. - Les clés d'un
Object
sont des chaînes de caractères ou des symboles (cf.Symbol
), alors que pour uneMap
ça peut être n'importe quelle valeur. - Il est possible d'obtenir facilement la taille d'une
Map
avecsize
. En revanche, pour unObject
il faudra compter « manuellement ». - Un objet
Map
est un itérable et on peut donc le parcourir directement. En revanche, itérer sur unObject
nécessite de récupérer les clés de l'objet pour ensuite les parcourir. - Un objet
Map
permettra d'obtenir de meilleures performances si on ajoute et supprime des éléments fréquemment.
Propriétés
Map.length
- La valeur de la propriété
length
est 0.
Attention, pour compter le nombre d'élément contenu dans uneMap
, on utilisera plutôtMap.prototype.size
. get Map[@@species]
- La fonction constructeur utilisée pour créer des objets dérivées.
Map.prototype
- Représente le prototype du constructeur
Map
. Permet l'addition de propriétés à tous les objetsMap
.
Instances de Map
Toutes les instances de Map
héritent de Map.prototype
.
Propriétés
Map.prototype.constructor
- Renvoie la fonction qui a créé l'instance du prototype. Par défaut, ce sera la fonction
Map
. Map.prototype.size
- Renvoie le nombre de paires de clé-valeur contenues dans l'objet
Map
.
Méthodes
Map.prototype.clear()
- Supprime toutes les paires de clé-valeur de l'objet
Map
. Map.prototype.delete(clé)
- Renvoie
true
si un élément contenu dans l'objetMap
existait avec cette clé et a été retiré. Si aucun élément n'existe dans l'objetMap
avec cette clé, c'estfalse
qui est renvoyé.Map.prototype.has(clé)
renverrafalse
après l'exécution de cette méthode. Map.prototype.entries()
- Renvoie un nouvel objet Iterator qui contient un tableau de
[clé, valeur]
pour chacun des éléments de l'objetMap
, dans leur ordre d'insertion. Map.prototype.forEach(callbackFn[, thisArg])
- Appelle la fonction
callbackFn
pour chaque paire clé-valeur de l'objetMap
dans leur ordre d'insertion. Si un paramètrethisArg
est fourni, il sera utilisé comme valeur pourthis
pour chaque appel de la fonction de retour (callback). Map.prototype.get(clé)
- Renvoie la valeur associée à la clé et
undefined
s'il n'y en a pas. Map.prototype.has(clé)
- Renvoie un booléen indiquant si une valeur associée à cette clé a été trouvée dans l'objet
Map
. Map.prototype.keys()
- Renvoie un nouvel objet
Iterator
contenant les clés de chaque élément de l'objetMap
dans leur ordre d'insertion. Map.prototype.set(clé, valeur)
- Définit la valeur d'un clé pour l'objet
Map
. Renvoieundefined
. Map.prototype.values()
- Renvoie un nouvel objet
Iterator
contenant les valeurs de chaque élément de l'objetMap
dans leur ordre d'insertion. Map.prototype[@@iterator]()
- Renvoie une nouvel objet
Iterator
qui contient un tableau de[clé, valeur]
pour chaque élément de l'objetMap
dans leur ordre d'insertion.
Exemples
Utiliser un objet 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 () {}
Utiliser NaN
comme clé
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"
Parcourir des objets 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"
Relation avec les objets 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"]
Cloner et fusionner des objets 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écifications
Spécification | État | Commentaires |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) La définition de 'Map' dans cette spécification. |
Standard | Définition initiale. |
ECMAScript (ECMA-262) La définition de 'Map' dans cette spécification. |
Standard évolutif |
Compatibilité des navigateurs
BCD tables only load in the browser