Back

Quelle est la différence entre Map, Set et Object en JavaScript ?

Quelle est la différence entre Map, Set et Object en JavaScript ?

Vous refactorisez un composant et devez stocker des paires clé-valeur. Par habitude, vous optez pour un objet, puis vous hésitez. Devrait-ce être une Map ? Un Set conviendrait-il mieux ici ? Cette décision compte plus qu’il n’y paraît : chaque structure possède des caractéristiques de performance et une sémantique distinctes qui affectent la clarté et l’efficacité de votre code.

Cette comparaison des structures de données JavaScript détaille les différences pratiques entre Map, Set et Object afin que vous puissiez faire le bon choix dans votre code de production.

Points clés à retenir

  • Les objets convertissent les clés en chaînes de caractères, tandis que les Maps préservent exactement le type des clés — cette distinction prévient les bugs subtils de collision.
  • Les Maps surpassent les Objects pour les ajouts et suppressions fréquents, alors que les Objects excellent dans les charges de travail orientées lecture avec des structures stables.
  • Les Sets offrent des vérifications d’appartenance en O(1) et disposent désormais de méthodes natives union, intersection et difference en JavaScript moderne.
  • Privilégiez les Objects pour les données structurées, optez pour les Maps lorsque les clés sont dynamiques ou non-string, et utilisez les Sets lorsque l’unicité est votre préoccupation principale.

Objectif principal : quand utiliser Map vs Set vs Object

La différence entre Map et Object en JavaScript se résume à l’intention et à la gestion des clés :

  • Object : Données structurées avec des clés string/symbol connues. Pensez configuration, props de composant, réponses d’API.
  • Map : Collections clé-valeur dynamiques où les clés peuvent être de n’importe quel type. Pensez caches, tables de correspondance avec des clés objet, ajouts et suppressions fréquents.
  • Set : Collections de valeurs uniques sans clés. Pensez déduplication, suivi d’éléments vus, vérifications d’appartenance.

Gestion des clés : la différence fondamentale entre Map et Object

Les objets convertissent les clés en chaînes de caractères. Les Maps préservent exactement le type des clés.

const obj = {}
obj[1] = 'number'
obj['1'] = 'string'
console.log(Object.keys(obj)) // ['1'] — collision

const map = new Map()
map.set(1, 'number')
map.set('1', 'string')
console.log(map.size) // 2 — clés distinctes

Les Maps acceptent également des objets comme clés — ce que les objets ne peuvent fondamentalement pas faire sans contournements de sérialisation.

const userCache = new Map()
const user = { id: 42 }
userCache.set(user, { lastSeen: Date.now() })

Consultez la documentation MDN pour Map pour la sémantique complète des clés.

Itération et sémantique d’ordre

Les trois structures ont un ordre d’itération défini, mais la sémantique diffère :

Map et Set : Ordre d’insertion pur. Toujours.

Object : Ordre d’insertion pour les clés string, mais les clés indexées par des entiers (par ex., '1', '42') sont triées numériquement en premier. Cela surprend les développeurs :

const obj = { b: 1, 2: 2, a: 3, 1: 4 }
console.log(Object.keys(obj)) // ['1', '2', 'b', 'a']

Les Maps et Sets sont directement itérables avec for...of. Les Objects nécessitent Object.keys(), Object.values() ou Object.entries().

Caractéristiques de performance à grande échelle

Pour la question de performance JavaScript Map vs Set vs Object, le contexte compte :

Les Objects excellent dans les charges de travail orientées lecture avec des clés string. Les moteurs modernes comme V8 optimisent l’accès aux propriétés via des classes cachées, rendant les lectures très rapides — lorsque la forme de l’objet reste stable.

Les Maps l’emportent pour les ajouts et suppressions fréquents. La suppression de propriété d’objet (via delete) peut déclencher une désoptimisation en invalidant les classes cachées. La spécification ECMAScript garantit un temps d’accès moyen sous-linéaire pour les Maps, sans imposer une implémentation interne spécifique.

Les Sets fournissent des vérifications d’appartenance en O(1) via has(), surpassant includes() des tableaux pour toute collection de taille non triviale.

Opérations natives sur les Sets

Set inclut désormais des méthodes intégrées pour les opérations courantes (voir la documentation MDN pour Set) :

const a = new Set([1, 2, 3])
const b = new Set([2, 3, 4])

a.union(b)               // Set {1, 2, 3, 4}
a.intersection(b)        // Set {2, 3}
a.difference(b)          // Set {1}
a.symmetricDifference(b) // Set {1, 4}
a.isSubsetOf(b)          // false

Ces méthodes sont largement supportées dans les navigateurs modernes.

Scénarios pratiques en frontend

Utilisez Object quand :

  • Vous définissez des props de composant ou une configuration
  • Vous travaillez avec la sérialisation JSON (les Maps ne se sérialisent pas directement)
  • Les clés sont connues au moment de l’écriture

Utilisez Map quand :

  • Les clés sont dynamiques ou fournies par l’utilisateur (évite la pollution de prototype)
  • Vous avez besoin de références d’objet comme clés
  • Le suivi de la taille importe (map.size vs Object.keys(obj).length)
  • Vous construisez des caches avec des mises à jour fréquentes

Utilisez Set quand :

  • Vous suivez des ID uniques ou des éléments vus
  • Vous dédupliquez des tableaux : [...new Set(array)]
  • Vous effectuez des tests d’appartenance rapides

Référence rapide

FonctionnalitéObjectMapSet
Types de clésstring, symboltousN/A (valeurs uniquement)
TailleObject.keys().length.size.size
Itérationindirectedirectedirecte
Support JSONnatifmanuelmanuel
Risque prototypeouinonnon

Conclusion

Le choix entre Map, Set et Object ne porte pas sur ce qui est « meilleur » — il s’agit d’adapter la structure de données à votre cas d’usage. Les objets restent le bon choix pour les données structurées avec des clés string. Les Maps gèrent proprement les scénarios clé-valeur dynamiques. Les Sets résolvent efficacement les problèmes d’unicité.

Privilégiez les objets par simplicité. Optez pour Map lorsque vous avez besoin de ses capacités spécifiques. Utilisez Set lorsque l’unicité est votre préoccupation principale.

FAQ

Pas directement. JSON.stringify ne gère pas les Maps nativement. Vous devez d'abord convertir la Map en tableau d'entrées en utilisant Array.from(map) ou l'opérateur spread, puis stringifier ce tableau. Pour la restaurer, parsez le JSON et passez le tableau résultant au constructeur Map : new Map(JSON.parse(jsonString)).

Les Maps gèrent les insertions et suppressions fréquentes sans la désoptimisation que la suppression de propriété d'objet peut causer. Elles suivent également la taille nativement avec la propriété size, acceptent n'importe quel type de valeur comme clé, y compris les nœuds DOM ou les références d'objet, et ne présentent aucun risque de pollution de prototype avec des clés fournies par l'utilisateur.

Ces méthodes sont désormais largement supportées dans les navigateurs modernes. Si vous devez supporter des environnements plus anciens, consultez les tableaux de compatibilité ou utilisez un polyfill.

Utilisez un tableau lorsque l'ordre d'insertion avec des doublons importe, lorsque vous avez besoin d'un accès basé sur l'index, ou lorsque la collection est suffisamment petite pour que le surcoût d'un Set ne soit pas justifié. Pour des collections plus grandes où l'unicité et les recherches rapides sont prioritaires, un Set est le meilleur choix.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay