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.
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 :
NaNest 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
Objectpossè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
Mapsont 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
Objectsont 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
Mapavecsize. En revanche, pour unObjectil faudra compter « manuellement ». - Un objet
Mapest un itérable et on peut donc le parcourir directement. En revanche, itérer sur unObjectnécessite de récupérer les clés de l'objet pour ensuite les parcourir. - Un objet
Mappermettra 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é
lengthest 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(en-US)- 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 (en-US).
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
truesi un élément contenu dans l'objetMapexistait avec cette clé et a été retiré. Si aucun élément n'existe dans l'objetMapavec cette clé, c'estfalsequi est renvoyé.Map.prototype.has(clé)renverrafalseaprè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
callbackFnpour chaque paire clé-valeur de l'objetMapdans leur ordre d'insertion. Si un paramètrethisArgest fourni, il sera utilisé comme valeur pourthispour chaque appel de la fonction de retour (callback). Map.prototype.get(clé)- Renvoie la valeur associée à la clé et
undefineds'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
Iteratorcontenant les clés de chaque élément de l'objetMapdans 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
Iteratorcontenant les valeurs de chaque élément de l'objetMapdans leur ordre d'insertion. Map.prototype[@@iterator]()- Renvoie une nouvel objet
Iteratorqui contient un tableau de[clé, valeur]pour chaque élément de l'objetMapdans 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)); // troisSpé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