Symbole

Les symboles sont relativement nouveaux introduite dans ES6. Une primitive de symbole représente une valeur unique entre en conflit avec une autre valeur, y compris celles d'autres primitives de symboles. Deux primitives de chaîne, composées de caractères identiques, s'apparentent strictement égal à:

String() === String()
> true

String( "My string." ) === String( "My string." );
> true

Cependant, deux symboles créés à l'aide de la fonction Symbol() ne peuvent jamais être strictement égal:

Symbol() === Symbol()
> false

Cette caractéristique vous permet d'utiliser des symboles comme clés de propriété uniques dans un objet, ce qui empêche des collisions avec des clés que tout autre code pourrait ajouter à cet objet.

const mySymbol = Symbol( "Desc" );

const myObject = {

}

myObject
> Object { Symbol("Desc"): "propSymbol" }

Il existe trois types de symboles:

  • Symboles créés avec Symbol()
  • Symboles partagés définis et récupérés depuis un registre de symboles global à l'aide de Symbol.for()
  • "Symboles connus" définies comme des propriétés statiques de l'objet Symbol. Ces symboles contiennent des méthodes internes qui ne peuvent pas être écrasées accidentellement.

Symbol() accepte une description (ou "nom du symbole") comme argument facultatif. Ces descriptions sont des étiquettes lisibles par l'homme qui sont utilisées à des fins de débogage. n'affecte pas l'unicité du résultat. Tout appel à Symbol renvoie une primitive de symbole totalement unique, même si plusieurs appels ont des valeurs descriptions:

Symbol( "My symbol." ) === Symbol( "My symbol." );
> false

Comme pour les autres types de données primitifs, les symboles héritent des méthodes et propriétés de leur prototype. Par exemple, vous pouvez accéder à une description en tant que propriété héritée du symbole créé:

let mySymbol = Symbol( "My symbol." );

mySymbol
.description
> "My symbol."

Toutefois, vous ne pouvez pas créer de symbole à l'aide du mot clé new:

let mySymbol = new Symbol();

> Uncaught TypeError: Symbol is not a constructor

Les symboles ne peuvent pas être énumérés, ce qui signifie que les propriétés symboliques ne sont pas disponibles lorsque vous utilisez des méthodes standards pour effectuer des itérations. getOwnPropertySymbols() donne accès aux propriétés de symbole d'un objet.

Symboles partagés

La méthode Symbol.for() tente de rechercher tous les symboles existants dans une registre de symboles global à l'échelle de l'environnement d'exécution avec une chaîne donnée comme clé et renvoie le symbole correspondant, le cas échéant. S'il n'en trouve pas, il crée un symbole. avec la clé spécifiée et l'ajoute au registre global:

let sharedSymbol = Symbol.for( "My key." );

sharedSymbol
=== Symbol.for( "My key." )
> true

Ces clés ne partagent aucun chevauchement fonctionnel avec les descriptions attribuées primitives Symbol créées par l'auteur. Pour accéder à un symbole dans le registre de symboles, vous devez d'abord le créer à l'aide de for():

Symbol( "String" ) === Symbol( "String" );
> false

Symbol( "String" ) === Symbol().for( "String" );
> false

Symbol().for( "String" ) === Symbol().for( "String" );
> true

Pour récupérer la clé d'un symbole dans le registre Symboles, utilisez Symbol.keyFor():

let mySymbol = Symbol.for( "Key." );

Symbol.keyFor( mySymbol ) ;
> "Key."

"Connu" symboles

Les symboles connus sont des propriétés statiques de l'objet Symbol, chacune d'entre elles est lui-même un symbole. Les symboles connus fournissent des clés de propriété uniques pour d'accéder aux méthodes intégrées de JavaScript et de les modifier, tout en empêchant les opérations de base ce comportement d'être écrasé involontairement.

Symbol;
> function Symbol()
    asyncIterator
: Symbol(Symbol.asyncIterator)
   
for: function for()
    hasInstance
: Symbol("Symbol.hasInstance")
    isConcatSpreadable
: Symbol("Symbol.isConcatSpreadable")
    iterator
: Symbol(Symbol.iterator)
    keyFor
: function keyFor()
    length
: 0
    match
: Symbol("Symbol.match")
    matchAll
: Symbol("Symbol.matchAll")
    name
: "Symbol"
    prototype
: Object { }
    replace
: Symbol("Symbol.replace")
    search
: Symbol("Symbol.search")
    species
: Symbol("Symbol.species")
    split
: Symbol("Symbol.split")
    toPrimitive
: Symbol("Symbol.toPrimitive")
    toStringTag
: Symbol("Symbol.toStringTag")
    unscopables
: Symbol("Symbol.unscopables")
   
<prototype>: function ()

Les symboles étant une fonctionnalité spécifique à ES6, ces valeurs symboliques sont destinés à être utilisés comme des "points d'extension" pour les développeurs qui modifient des fichiers JavaScript sans introduire de problèmes de rétrocompatibilité.

Les valeurs de symboles connues sont souvent stylisées avec un Préfixe @@ ou encapsulé dans % pour différencier leurs clés de leurs prototypes modifiables. Exemple : @@match (ou %match%) est une référence à l'objet Symbol.match immuable, et non String.prototype.match

Testez vos connaissances

Pouvez-vous utiliser new pour créer un symbole ?

Oui
Non

Parmi les propositions suivantes, lesquelles décrivent des symboles "connus" ?

Symboles que vous utilisez fréquemment
Propriétés statiques de l'objet "Symbol"
Clés de propriété uniques pour accéder aux paramètres JavaScript et les modifier méthodes intégrées