Hashmap JavaScript - Map, WeakMap ou Objet simple?

Noël Besnard .

18 mai 2026

Exemple de code JavaScript montrant l'utilisation d'un `hashmap` (Map) pour stocker des données, associant un tableau à `true`, un nom à 'Ray' et un âge à 21.

En JavaScript, une structure clé-valeur devient vite indispensable dès qu’il faut retrouver, mettre à jour ou supprimer des données sans parcourir tout un tableau. La vraie question n’est pas seulement de stocker des paires, mais de choisir une structure qui reste lisible, sûre et cohérente avec le comportement du langage. Dans cet article, je passe en revue la table de hachage côté JavaScript, la place de `Map`, les cas où `Object` reste plus simple, et les pièges qui reviennent le plus souvent.

Ce qu’il faut retenir avant d’écrire un dictionnaire clé-valeur

  • `Map` est la structure native la plus proche d’une table de hachage moderne en JavaScript.
  • Les clés d’une `Map` peuvent être de n’importe quel type, et l’ordre d’itération suit l’insertion.
  • `Object` reste pertinent pour des données JSON simples ou des schémas stables.
  • `WeakMap` sert surtout à attacher des données à des objets sans bloquer leur collecte mémoire.
  • Avec des clés objet, la comparaison se fait par référence, pas par contenu.
  • Si vous devez sérialiser, anticipez la conversion avant d’écrire le code de production.

Ce que fait réellement une table de hachage en JavaScript

Une table de hachage associe une clé à une valeur pour retrouver l’information rapidement. En pratique, on attend quatre gestes simples: ajouter, lire, vérifier l’existence, supprimer. La spécification ECMAScript demande des temps d’accès en moyenne sublinéaires; selon le moteur, l’implémentation peut donc s’appuyer sur une table de hachage, un arbre ou une autre structure interne. Autrement dit, le détail bas niveau compte moins que le contrat que vous donne l’API. La documentation MDN rappelle aussi qu’une Map garde des clés uniques et une itération dans l’ordre d’insertion.

Cette nuance vaut la peine d’être gardée en tête, parce qu’elle explique pourquoi on ne choisit pas la structure au hasard. Quand la clé est dynamique et que l’ordre d’insertion a de la valeur, Map devient presque toujours le point de départ naturel.

Graphique comparant la performance d'insertion d'un objet JavaScript et d'une Map. La Map est plus rapide.

Pourquoi Map est souvent le meilleur point de départ

Quand je veux un vrai dictionnaire en JavaScript, je prends Map presque sans hésiter. L’API est claire, l’ordre d’insertion est conservé, la taille se lit avec size, et les clés peuvent être de n’importe quel type, y compris des objets. La comparaison des clés suit SameValueZero: NaN est considéré comme égal à NaN, et deux références d’objets ne sont égales que si elles pointent vers le même objet.

Critère Map Object
Types de clés N’importe quelle valeur Chaînes et Symboles, avec coercition fréquente en usage dictionnaire
Itération Ordre d’insertion Règles d’énumération du langage, moins directes pour un dictionnaire
Taille size Object.keys(...).length
Clés objet Comparées par référence Peu adapté comme dictionnaire d’objets sans transformation
Usage typique Caches, index, compteurs, relations dynamiques Configurations, JSON, structures fixes

Si vous avez besoin d’une structure explicite, prévisible et facile à parcourir, Map fait très bien le travail. Et si vos données doivent vivre longtemps, le fait de ne pas dépendre du prototype d’un objet est un avantage concret, pas un détail théorique. Une fois ce choix posé, le vrai intérêt devient la mise en œuvre concrète.

Construire une hashmap simple avec Map

Créer, lire, vérifier, supprimer

Le cycle de base tient en quatre méthodes: set(), get(), has() et delete(). Je conseille de les garder en tête comme le vocabulaire naturel d’une table de hachage, parce qu’elles disent exactement ce que le code fait.

const stock = new Map();

stock.set("router", 14);
stock.set("firewall", 3);

console.log(stock.get("router")); // 14
console.log(stock.has("switch")); // false
stock.delete("firewall");

console.log(stock.size); // 1
Deux détails comptent ici. D’abord, set() retourne la map elle-même, ce qui permet l’enchaînement. Ensuite, get() renvoie undefined si la clé est absente, donc has() reste la méthode fiable quand undefined peut être une valeur légitime.

Lire aussi : GET vs POST - Le guide pour des requêtes HTTP parfaites

Compter des occurrences sans bricolage

Le cas d’usage le plus courant, à mon sens, reste le compteur. Tags, mots, événements, identifiants de session: dès qu’une clé peut revenir plusieurs fois, Map donne un code court et lisible.

function countWords(words) {
  const counts = new Map();

  for (const word of words) {
    counts.set(word, (counts.get(word) ?? 0) + 1);
  }

  return counts;
}

const result = countWords(["api", "cache", "api", "map", "cache", "api"]);

for (const [word, count] of result) {
  console.log(word, count);
}

Je trouve ce schéma particulièrement propre pour les statistiques, les labels ou les caches de calcul. Si vous devez ensuite repartir vers un objet simple, Object.fromEntries(result) transforme une liste de paires en objet, à condition que la forme cible corresponde bien à vos besoins de sérialisation.

Reste à savoir quand l’objet nu suffit encore, ce qui évite de surdimensionner votre structure.

Quand Object suffit encore

Je garde Object quand les clés sont connues à l’avance, que les données ressemblent à une configuration ou à un payload JSON, et que je n’ai pas besoin des clés non textuelles. Dans ce cas, la structure est simple, directe et très lisible pour toute l’équipe. Si je veux un dictionnaire pur à base de chaînes, je crée souvent un objet sans prototype avec Object.create(null) pour éviter les propriétés héritées.

const labels = Object.create(null);

labels.fr = "Français";
labels.en = "English";

console.log(Object.keys(labels)); // ["fr", "en"]

Ce choix est utile quand l’écosystème autour du code attend un objet classique, par exemple pour des échanges JSON ou des schémas de configuration. En revanche, si vous commencez à empiler des opérations de recherche, des suppressions et des clés dynamiques, je passe vite sur Map, parce que le code devient moins ambigu. La question suivante devient alors celle du cycle de vie des données, et c’est là que WeakMap change complètement de logique.

Le rôle discret de WeakMap dans les objets liés au cycle de vie

WeakMap n’est pas une version "allégée" de Map; c’est un outil différent, pensé pour des associations qui ne doivent pas retenir leurs clés en mémoire. Les clés doivent être des objets ou des symboles non enregistrés, et la collection n’est pas itérable. C’est idéal pour stocker des métadonnées sur des instances, des nœuds DOM ou des objets temporaires sans empêcher le garbage collector de faire son travail.

const metadata = new WeakMap();

function attach(node, info) {
  metadata.set(node, info);
}

function read(node) {
  return metadata.get(node);
}

Je l’utilise surtout quand la donnée appartient au cycle de vie de l’objet clé, pas quand elle doit être listée, exportée ou comptée. Dès qu’on a besoin d’un inventaire, d’une taille ou d’une boucle de parcours, WeakMap n’est plus le bon outil.

Les erreurs que je vois le plus souvent

  • Utiliser map["clé"] au lieu de map.get("clé"), puis croire que la donnée a disparu.
  • Tester get() sans has() alors que undefined peut être une valeur volontaire.
  • Créer un nouvel objet littéral pour relire une clé objet, alors qu’une Map compare par référence.
  • Vouloir sérialiser une Map telle quelle dans du JSON sans conversion préalable.
  • Choisir WeakMap alors qu’il faut itérer ou exposer les entrées.
  • Employer Object comme dictionnaire sans penser au prototype, alors que Object.create(null) aurait suffi.

Il y a aussi un détail plus subtil: la comparaison de clés dans Map suit SameValueZero. Concrètement, NaN correspond à NaN, et les deux zéros ne sont pas distingués. C’est rarement bloquant, mais c’est le genre de nuance qui évite un diagnostic inutile en production. À partir de là, le bon réflexe consiste surtout à choisir la structure selon la durée de vie des données et la forme de vos clés.

Le réflexe que j’applique entre Map, Object et WeakMap

Mon choix tient en une règle simple. Map dès que je pense dictionnaire dynamique, compteur, cache ou relation clé-valeur avec itération fiable. Object dès que la structure est stable, JSON-friendly, et qu’elle ressemble davantage à un modèle de données qu’à un registre. WeakMap quand j’attache des informations à des objets sans vouloir bloquer leur collecte mémoire.

Si la structure devient centrale dans un chemin critique, je ne devine pas le comportement du moteur: je mesure sur des données réalistes. Dans un projet web, c’est souvent là que se joue la différence entre un code qui reste simple à maintenir et un code qui s’encombre de contournements inutiles. En pratique, quand je veux une vraie hashmap en JavaScript, je pars presque toujours de Map, puis je ne descends vers Object ou WeakMap que si le besoin est vraiment plus précis.

Questions fréquentes

`Map` permet d'utiliser n'importe quel type de valeur comme clé (y compris des objets) et maintient l'ordre d'insertion, offrant une API claire pour la gestion des données. `Object` se limite aux chaînes et Symboles comme clés et n'assure pas l'ordre d'itération, étant plus adapté aux configurations ou données JSON statiques.
Privilégiez `Map` pour les dictionnaires dynamiques, les compteurs, les caches ou toute relation clé-valeur nécessitant une itération fiable et la conservation de l'ordre d'insertion. C'est le choix par défaut pour une hashmap moderne et flexible.
`Object` est pertinent lorsque les clés sont connues à l'avance, que les données ressemblent à une configuration ou un payload JSON, et que vous n'avez pas besoin de clés non textuelles ou d'un ordre d'itération garanti. Utilisez `Object.create(null)` pour éviter les propriétés héritées.
`WeakMap` est conçu pour associer des métadonnées à des objets sans empêcher leur collecte par le garbage collector. Ses clés doivent être des objets (ou Symboles non enregistrés) et elle n'est pas itérable. C'est idéal pour des données liées au cycle de vie d'un objet, comme des informations privées sur des instances DOM.
Évitez d'utiliser `map["clé"]` au lieu de `map.get("clé")`, de ne pas utiliser `has()` avant `get()` si `undefined` est une valeur valide, de tenter de sérialiser une `Map` directement en JSON, ou de choisir `WeakMap` si vous avez besoin d'itérer sur les entrées.

Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

quand utiliser map javascript hashmap javascript différence map weakmap javascript implémenter hashmap javascript
Autor Noël Besnard
Noël Besnard
Je suis Noël Besnard, un analyste de l'industrie passionné par les domaines de la technologie, notamment le web, l'intelligence artificielle, les réseaux et la sécurité. Avec plus de dix ans d'expérience dans l'analyse des tendances du marché technologique, j'ai acquis une expertise approfondie qui me permet d'explorer les innovations et les défis auxquels notre monde numérique est confronté. Mon approche consiste à simplifier des données complexes et à fournir une analyse objective, ce qui me permet de rendre les sujets techniques accessibles à tous. Je m'engage à offrir des informations précises et à jour, en vérifiant rigoureusement les faits pour garantir la fiabilité de chaque article que je publie. Mon objectif est d'aider les lecteurs à naviguer dans cet univers en constante évolution, en leur fournissant les outils nécessaires pour comprendre les enjeux technologiques contemporains.

Commentaires (0)

Ajouter un commentaire