MISE À JOUR : Récemment, un brillant article de Mozilla a été publié. Lisez-le si vous êtes curieux.
Comme vous le savez peut-être, ils prévoient d'inclure un nouveau type primitif de symbole dans ECMAScript 6 (sans parler d'autres choses folles). J'ai toujours pensé que la :symbol
notion de Ruby était inutile; nous pourrions facilement utiliser des chaînes simples à la place, comme nous le faisons en JavaScript. Et maintenant, ils décident de compliquer les choses avec JS.
Je ne comprends pas la motivation. Quelqu'un pourrait-il m'expliquer si nous avons vraiment besoin de symboles en JavaScript?
private
etpublic
des mots-clés d'attribut de classe qu'ils ont décidé d'abandonner pour une implémentation de classe plus simple. Au lieu dethis.x = x
vous, vous étiez censé le fairepublic x = x
et pour des variables privéesprivate y = y
. Ils ont décidé d'abandonner cela pour une implémentation de classe beaucoup plus minimale. Symbol serait alors une solution de contournement requise pour obtenir des propriétés privées dans l'implémentation minimale.Réponses:
La motivation initiale pour introduire des symboles dans Javascript était d'activer les propriétés privées .
Malheureusement, ils ont fini par être fortement dégradés. Ils ne sont plus privés, car vous pouvez les trouver via la réflexion, par exemple, à l'aide de
Object.getOwnPropertySymbols
ou des procurations.Ils sont désormais connus sous le nom de symboles uniques et leur seule utilisation prévue est d'éviter les conflits de noms entre les propriétés. Par exemple, ECMAScript lui-même peut désormais introduire des hooks d'extension via certaines méthodes que vous pouvez mettre sur des objets (par exemple pour définir leur protocole d'itération) sans risquer de les heurter avec les noms d'utilisateurs.
Que ce soit une motivation assez forte pour ajouter des symboles à la langue est discutable.
la source
Object.getOwnPropertySymbols
n'est pas la seule fuite; la plus difficile est la possibilité d'utiliser des procurations pour intercepter l'accès à une propriété "privée".Les symboles ne garantissent pas une véritable confidentialité mais peuvent être utilisés pour séparer les propriétés publiques et internes des objets. Prenons un exemple où nous pouvons utiliser
Symbol
pour avoir des propriétés privées.Prenons un exemple où une propriété d'un objet n'est pas privée.
Ci-dessus, la
Pet
propriété de classetype
n'est pas privée. Pour le rendre privé, nous devons créer une fermeture. L'exemple ci-dessous illustre comment nous pouvons rendretype
privé en utilisant une fermeture.Inconvénient de l'approche ci-dessus: nous introduisons une fermeture supplémentaire pour chaque
Pet
instance créée, ce qui peut nuire aux performances.Maintenant, nous vous présentons
Symbol
. Cela peut nous aider à rendre une propriété privée sans utiliser de fermetures inutiles supplémentaires. Exemple de code ci-dessous:la source
_
ne garantit pas une véritable confidentialité mais peut être utilisé pour séparer les propriétés publiques et internes des objets. En d'autres termes, réponse inutile.Symbols
sont un nouveau type d'objet spécial qui peut être utilisé comme nom de propriété unique dans les objets. UtiliserSymbol
au lieu destring
permet à différents modules de créer des propriétés qui n'entrent pas en conflit les unes avec les autres.Symbols
peuvent également être rendus privés, afin que leurs propriétés ne soient pas accessibles à toute personne qui n'a pas déjà un accès direct à laSymbol
.Symbols
sont une nouvelle primitive . Tout comme lesnumber
,string
etboolean
primitives,Symbol
une fonction qui peut être utilisée pour les créer. Contrairement aux autres primitives, ellesSymbols
n'ont pas de syntaxe littérale (par exemple, commentstring
ont''
) - la seule façon de les créer est avec leSymbol
constructeur de la manière suivante:En réalité,
Symbol
les sont juste une manière légèrement différente d'attacher des propriétés à un objet - vous pouvez facilement fournir lesSymbols
méthodes standard bien connues, tout comme cellesObject.prototype.hasOwnProperty
qui apparaissent dans tout ce qui hériteObject
.Voici quelques-uns des avantages du
Symbol
type primitif.Symbols
ont une capacité de débogage intégréeSymbols
peut être donné une description, qui est vraiment juste utilisée pour le débogage pour vous faciliter la vie lorsque vous les connectez à une console.Symbols
peut être utilisé commeObject
cléC'est là
Symbol
que ça devient vraiment intéressant. Ils sont fortement entrelacés avec des objets.Symbol
peuvent être attribués en tant que clés à des objets, ce qui signifie que vous pouvez attribuer un nombre illimité d'uniquesSymbol
à un objet et être assuré que celles-ci n'entreront jamais en conflit avec desstring
clés ou d'autres uniquesSymbols
.Symbols
peut être utilisé comme une valeur unique.Supposons que vous avez une bibliothèque d'enregistrement, qui comprend plusieurs niveaux de journaux tels que
logger.levels.DEBUG
,logger.levels.INFO
,logger.levels.WARN
et ainsi de suite. Dans le code ES5, vous souhaitez créer cesstring
s (sologger.levels.DEBUG === 'debug'
) ounumber
s (logger.levels.DEBUG === 10
). Les deux ne sont pas idéales car ces valeurs ne sont pas des valeurs uniques, mais lesSymbol
s le sont! Devient donclogger.levels
simplement:En savoir plus dans cet excellent article .
la source
log.levels = {DEBUG: Symbol('debug')
et pas simplementlog.levels = {DEBUG:'debug'}
. à la fin c'est pareil. Je pense qu'il convient de mentionner que les symboles sont invisibles lors de l'itération sur les clés d'un objet. c'est leur "truc"{}
et obtenir le même résultat (comme valeur unique), ou peut-être un littéral est préféré dans ce projet, ou vous pouvez dire qu'il faut d'abord lire le doc.) I pense personnellement qu'il offre une bonne lisibilité de sens unique dans le codeSymbol("some message")
devient{message:'some message'}
, sans doute, l'objet fait mieux ici car vous pouvez ajouter plusieurs champs.Cet article concerne le
Symbol()
, fourni avec des exemples réels que j'ai pu trouver / faire et des faits et définitions que j'ai pu trouver.TLDR;
C'est
Symbol()
le type de données, introduit avec la sortie d'ECMAScript 6 (ES6).Il y a deux faits curieux sur le symbole.
le premier type de données et le seul type de données en JavaScript qui n'a pas de littéral
toute variable, définie avec
Symbol()
, obtient un contenu unique, mais ce n'est pas vraiment privé .toutes les données ont leur propre symbole, et pour les mêmes données, les symboles seraient les mêmes . Plus d'informations dans le paragraphe suivant, sinon ce n'est pas un TLRD; :)
Comment initialiser le symbole?
1. Pour obtenir un identifiant unique avec une valeur débogable
Vous pouvez le faire de cette façon:
Ou de cette façon:
le
"some text here"
chaîne ne peut pas être extraite du symbole, c'est juste une description à des fins de débogage. Cela ne change en rien le comportement du symbole. Bien que vous puissiez leconsole.log
faire (ce qui est juste, car la valeur est pour le débogage, afin de ne pas confondre ce journal avec une autre entrée de journal):2. Pour obtenir un symbole pour certaines données de chaîne
Dans ce cas, la valeur du symbole est réellement prise en compte et de cette façon, deux symboles peuvent être non uniques.
Appelons ces symboles des symboles de "deuxième type". Ils ne se croisent pas avec les symboles de "premier type" (c'est-à-dire ceux définis avec
Symbol(data)
en aucune façon les ).Les deux paragraphes suivants ne concernent que le symbole de premier type .
Comment puis-je bénéficier de l'utilisation de Symbol au lieu des anciens types de données?
Prenons d'abord un objet, un type de données standard. Nous pourrions y définir des paires clé-valeur et avoir accès aux valeurs en spécifiant la clé.
Et si nous avons deux personnes du nom de Peter?
Ce faisant:
n'aurait pas beaucoup de sens.
Il semble donc que deux personnes absolument différentes aient le même nom. Parlons alors de nouveau
Symbol()
. C'est comme une personne dans la vraie vie - toute personne est unique , mais leurs noms peuvent être égaux. Définissons deux "personnes".Maintenant, nous avons deux personnes différentes portant le même nom. Nos personnes sont-elles vraiment différentes? Elles sont; vous pouvez vérifier ceci:
Comment en bénéficions-nous?
Nous pouvons faire deux entrées dans votre objet pour les différentes personnes et elles ne peuvent en aucun cas être confondues.
En utilisant cette initialisation, il est absolument impossible de confondre les entrées pour les première et deuxième personnes. Les appeler
console.log
affichera correctement leurs seconds noms.Lorsqu'il est utilisé dans un objet, en quoi est-il différent de la définition d'une propriété non énumérable?
En effet, il existait déjà un moyen de définir une propriété à cacher
Object.keys
et à énumérer. C'est ici:Quelle différence
Symbol()
y apporte-t-il? La différence est que vous pouvez toujours obtenir la propriété définie avecObject.defineProperty
de la manière habituelle:Et si défini avec Symbol comme dans le paragraphe précédent:
Vous n'aurez la possibilité de recevoir sa valeur que si vous connaissez sa variable, c'est-à-dire
De plus, la définition d'une autre propriété sous la clé
"apple"
fera en sorte que l'objet supprime l'ancienne (et s'il est codé en dur, il pourrait générer une erreur). Alors, plus de pommes! C'est dommage. Se référant au paragraphe précédent, les symboles sont uniques et définissent une clé commeSymbol()
qui la rendra unique.Conversion de type et vérification
Contrairement à d'autres types de données, il est impossible de convertir le
Symbol()
en n'importe quel autre type de données.Il est possible de "créer" un symbole basé sur le type de données primitif en appelant
Symbol(data)
.En termes de vérification du type, rien ne change.
la source
Voici comment je le vois. Les symboles offrent «un niveau supplémentaire de confidentialité», en empêchant les clés / propriétés d'un objet d'être exposées via certaines méthodes populaires telles que Object.keys () et JSON.stringify ().
Bien qu'un objet en soi soit donné, de telles propriétés peuvent toujours être exposées via la réflexion, le proxy, Object.getOwnPropertySymbols (), etc.
la source
Un symbole JS est un nouveau type de données primitif. Ce sont des jetons qui servent d'identifiants uniques . Un symbole peut être créé à l'aide du
Symbol
constructeur. Prenez par exemple cet extrait de MDN:Il est souvent pratique d'utiliser des symboles comme clés de propriété d'objet uniques, par exemple:
la source
La source
la source