Selon la spécification, les clés d'attribut d'objet ne peuvent être que de type chaîne ou de type symbole, pas de nombre ou de booléen, uniquement de chaîne et Il existe deux types de symboles.
Nous comparons généralement les chaînes d'attributs, regardons maintenant les avantages que nous apporte le type de symboles.
La valeur "Symbole" représente un identifiant unique utilisant le nom donné. Des valeurs de ce type peuvent être créées comme ceci : Symbol(name)
:
// id is a symbol with the name "id" let id = Symbol("id");
Les symboles garantissent l'unicité et produiront des valeurs différentes même si nous utilisons le même nom. Par exemple, voici deux symboles portant le même nom, les deux ne sont pas égaux :
let id1 = Symbol("id"); let id2 = Symbol("id"); alert(id1 == id2); // false
Si vous êtes familier avec Ruby ou d'autres langages, il y a le même type de symboles, ne vous y trompez pas, Les symboles Javascript sont différents.
le symbole permet la création de propriétés cachées d'un objet afin qu'un autre code n'y accède pas ou ne les écrase pas accidentellement.
Par exemple, si on veut stocker "l'identifiant" de l'objet utilisateur, on peut créer un symbole d'id :
Laissez l'utilisateur = { nom : "John" } ;
Soit id = Symbol("id");
user[id] = "ID Value"; alert( user[id] ); // we can access the data using the symbol as the key
Imaginons maintenant qu'un autre script veuille ajouter son propre attribut "id" à l'objet utilisateur dans son propre but. Il s'agit peut-être d'une autre bibliothèque Javascript, donc ils ne se connaissent pas du tout.
Pas de problème, soyez capable de créer le vôtre Symbol("id")
.
Le code est le suivant :
// ... let id = Symbol("id"); user[id] = "Their id value";
Ceci est sans conflit car les symboles sont toujours différents, même avec le même nom. Notez que si nous utilisons la chaîne "id" au lieu du symbole pour atteindre le même objectif, il y aura un conflit :
let user = { name: "John" }; // our script uses "id" property user.id = "ID Value"; // ...if later another script the uses "id" for its purposes... user.id = "Their id value" // boom! overwritten! it did not mean to harm the colleague, but did it!
Si nous utilisons le symbole dans un littéral object, nous devons utiliser des crochets :
let id = Symbol("id"); let user = { name: "John", [id]: 123 // not just "id: 123" };
car nous avons besoin de la valeur de la variable symbole nommée "id", pas de la chaîne "id".
L'attribut symbol ne participe pas à la boucle for..in, par exemple :
let id = Symbol("id"); let user = { name: "John", age: 30, [id]: 123 }; for(let key in user) alert(key); // name, age (no symbols) // the direct access by the symbol works alert( "Direct: " + user[id] );
Pour le moment , une partie du concept est généralement cachée, s'il s'agit d'autres scripts ou d'une bibliothèque, et n'attend pas non plus l'accès à la propriété symbol.
En revanche, Object.assign copie à la fois les attributs de caractères et les attributs de symboles.
let id = Symbol("id"); let user = { [id]: 123 }; let clone = Object.assign({}, user); alert( clone[id] ); // 123
Il n'y a pas de contradiction entre les deux. C'est ainsi que la spécification est conçue. L'idée est que lorsque nous clonons ou fusionnons des objets, nous voulons généralement que l'attribut du symbole soit également copié.
D'autres types de clés d'attribut doivent être convertis de force en chaînes :
Les clés des objets ne peuvent utiliser que des chaînes ou des symboles, et les autres types doivent être convertis de force en chaînes.
let obj = { 0: "test" // same as "0": "test" } // both alerts access the same property (the number 0 is converted to string "0") alert( obj["0"] ); // test alert( obj[0] ); // test (same property)
Habituellement, tous les symboles sont différents, mais parfois nous voulons que les symboles avec le même nom soient identiques. Par exemple, si nous voulons accéder au symbole avec le nom « id » dans différentes parties de l’application, il doit bien sûr être le même.
Ceci peut être réalisé grâce à l'enregistrement global des symboles. Nous pouvons d'abord les créer, puis y accéder, et garantir que le même symbole est obtenu grâce à un accès répété avec le même nom.
est créé ou lu dans l'enregistrement. La syntaxe d'utilisation est : symbol.for(name)
, par exemple :
// read from the global registry let name = Symbol.for("name"); // if the symbol did not exist, it is created // read it again let nameAgain = Symbol.for("name"); // the same symbol alert( name === nameAgain ); // true
Le symbole dans l'enregistrement est appelé le symbole global. symbole à l’échelle de l’application, le code est accessible et des symboles globaux peuvent être utilisés.
Dans d'autres langages de programmation, comme Ruby, chaque nom a un seul symbole. En JavaScript, on sait que c'est le symbole global.
Pour les symboles globaux, non seulement Symbol.for(name)
renvoie le symbole basé sur le nom, mais a également l'appel opposé : Symbol.keyFor(name)
, qui a la fonction opposée : renvoie le nom basé sur le symbole global.
Exemple :
let sym = Symbol.for("name"); let sym2 = Symbol.for("id"); // get name from symbol alert( Symbol.keyFor(sym) ); // name alert( Symbol.keyFor(sym2) ); // id
Symbol.keyfor est implémenté en interne, utilise l'enregistrement global des symboles et recherche les noms de symboles en fonction du symbole.
Il n'a donc aucun effet sur les symboles non globaux, s'il ne s'agit pas d'un symbole global, il ne sera pas trouvé et undéfini sera renvoyé.
Exemple :
alert( Symbol.keyFor(Symbol.for("name")) ); // name, global symbol alert( Symbol.keyFor(Symbol("name2")) ); // undefined, non-global symbol
Symbole non global, le nom est uniquement destiné à des fins de débogage.
Il existe de nombreux symboles système dans Javascript, et nous pouvons les utiliser pour ajuster divers aspects de l'objet.
Voici quelques symboles couramment utilisés :
Symbol.hasInstance
Symbol.isConcatSpreadable
Symbol.iterator
Symbol.toPrimitive
…
Exemple : Symbol.toPrimitive
Utilisé pour décrire des objets lors de la conversion d'objets en types de base. Si vous continuez à étudier Javascript en profondeur, vous vous familiariserez progressivement avec les autres.
le symbole est un type de base qui implémente une identification unique
Créer un symbolesymbol(name)
🎜>
Techniquement, les symboles ne sont pas masqués à 100 %. Il existe des méthodes intégrées Object.getOwnPropertySymbols(obj)
pour obtenir tous les symboles.
Il existe également une méthode Reflect.ownKeys(obj)
qui renvoie toutes les clés de l'objet, y compris le symbole.
Donc ce n’est pas vraiment caché. Mais la plupart des méthodes intégrées à la bibliothèque et des constructions syntaxiques suivent une convention commune selon laquelle elles sont cachées, et si quelqu'un appelle explicitement la méthode ci-dessus, il peut parfaitement comprendre ce qu'il fait.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!