Les symboles

ES6 introduit un nouveau type primitif : les symboles. Un symbole représente une valeur unique est non modifiable.

let s = Symbol();

Un symbole se crée sans utiliser l’opérateur new. Un symbole est bien un type :

let s = Symbol();
console.log(typeof s); // Affiche symbol

Il est possible de créer un symbole en lui donnant une valeur. Cependant, deux symboles avec la même valeur ne sont pas identiques.

let s1 = Symbol("mon symbole");
let s2 = Symbol("mon symbole");

console.log(s1 === s2); // Affiche false

Il est possible de créer ou de récupérer un symbole existant grâce à la fonction Symbol.for.

let s1 = Symbol.for("mon symbole");
let s2 = Symbol.for("mon symbole");

console.log(s1 === s2); // Affiche true

Les symboles comme noms de propriétés

Les symboles ont été introduits pour être utilisés comme noms de certaines propriétés.

let s = Symbol();

let o = {};
o[s] = function() {
    // une méthode
}

On peut également utiliser un symbole dans une déclaration littérale.

let s1 = Symbol();
let s2 = Symbol();

let o = {
    name: "mon objet",
    [s1]: "mon symbole",
    [s2]() {
        // une méthode
    }
};

well-known symbols

Il existe une liste de symboles pré-définis appelés en anglais les well-known symbols. Dans la documentation, ces symboles sont notés en commençant par @@ mais ils sont accessibles directement à partir de Symbol :

  • Symbol.iterator (noté @@iterator)

  • Symbol.match (noté @@match)

  • Symbol.search (noté @@search)

  • Symbol.replace (noté @@replace)

  • Symbol.split (noté @@split)

  • Symbol.hasInstance (noté @@hasInstance)

  • Symbol.species (noté @@species)

  • Symbol.unscopables (noté @@unscopables)

  • Symbol.isContcatSpreadable (noté @@isContcatSpreadable)

  • Symbol.toPrimitive (noté @@toPrimitive)

  • Symbol.toStringTag (noté @@toStringTag)

Ces symboles sont utilisés pour définir des propriétés ou des méthodes qui vont modifier le comportement d’une objet. Par exemple, le symbole @@toPrimitive permet de définir une méthode qui sera appelée quand un objet doit être converti en une primitive.

let o = {
    [Symbol.toPrimitive](type) {
        switch(type) {
            case "number":
                return 1;
            case "string":
                return "hello";
            default:
                return null;
        }
    }
}

console.log(Number(o)); // Affiche 1
console.log(String(o)); // Affiche hello

Nous verrons dans le chapitre consacré aux itérateurs que le symbole @@iterator est utilisé pour définir un objet itérable.