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 ?
Parmi les propositions suivantes, lesquelles décrivent des symboles "connus" ?