Symbol en JavaScript : une clé de propriété qui n'entre jamais en collision

Un Symbol est une valeur unique par construction, utilisée comme clé de propriété discrète et pour brancher un objet sur les mécanismes du langage.
3 min de lecture
Believemy logo

Ajouter une propriété à un objet qui ne vous appartient pas est une opération risquée : si une bibliothèque écrit obj.id et qu'une autre fait pareil, la seconde efface la première sans bruit.

Le symbole résout ce problème à la racine, en fournissant une clé que personne d'autre ne peut fabriquer par hasard.


Définition

Un Symbol est une valeur primitive unique et immuable, créée par l'appel Symbol(). Deux symboles ne sont jamais égaux, même créés avec la même description.

JAVASCRIPT
const a = Symbol("id");
const b = Symbol("id");

console.log(a === b);        // false
console.log(a.description);  // "id"
console.log(typeof a);       // "symbol"

La description ne sert qu'au débogage : elle apparaît dans les messages et dans la console, sans jamais participer à la comparaison. C'est ce qui distingue un symbole d'une chaîne, avec laquelle deux valeurs identiques sont la même clé.


Une clé de propriété discrète

Un symbole s'utilise comme clé entre crochets. La propriété existe et se lit normalement, mais elle échappe aux parcours ordinaires.

JAVASCRIPT
const INTERNE = Symbol("interne");
const compte = { nom: "Ada", [INTERNE]: "jeton" };

console.log(Object.keys(compte));      // [ 'nom' ]
console.log(JSON.stringify(compte));   // {"nom":"Ada"}
console.log(compte[INTERNE]);          // "jeton"

Ni Object (objet).keys, ni une boucle in, ni JSON.stringify ne voient cette clé. La donnée voyage avec l'objet sans polluer sa forme publique, ce qui est exactement l'usage recherché par les bibliothèques.


Les symboles bien connus

Le langage réserve quelques symboles pour brancher un objet sur ses propres mécanismes. Le plus utile est Symbol.iterator, qui rend un objet parcourable par of et dépliable par Spread (...).

JAVASCRIPT
const semaine = {
  jours: ["lundi", "mardi", "mercredi"],
  [Symbol.iterator]() {
    let i = 0;
    const { jours } = this;
    return {
      next: () =>
        i < jours.length
          ? { value: jours[i++], done: false }
          : { value: undefined, done: true },
    };
  },
};

for (const jour of semaine) console.log(jour);
console.log([...semaine]);   // [ 'lundi', 'mardi', 'mercredi' ]


Questions fréquentes

Question

Pourquoi new Symbol() lève-t-il une erreur ?

Parce qu'un symbole est une primitive, au même titre qu'un nombre ou un booléen, et non un objet à construire. Le new lève une TypeError disant que Symbol n'est pas un constructeur. La fonction s'appelle directement.

Question

Une propriété par symbole est-elle vraiment privée ?

Non, elle est discrète. Object.getOwnPropertySymbols les liste toutes, et qui détient le symbole lit la valeur. Pour de la confidentialité réelle, ce sont les champs privés d'une class, préfixés par un dièse, qu'il faut employer.

Question

À quoi sert Symbol.for ?

À partager un symbole entre plusieurs morceaux de code. Symbol.for("app.id") consulte un registre global et rend toujours la même valeur, là où Symbol("app.id") en crée une nouvelle à chaque appel. À réserver aux cas où le partage est voulu.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.