Fermer

avril 10, 2018

Symboles et leurs utilisations –


Alors qu'ES2015 a introduit de nombreuses fonctionnalités linguistiques qui figuraient sur les listes de souhaits des développeurs depuis un certain temps, certaines nouvelles fonctionnalités sont moins connues et comprises, et les avantages sont beaucoup moins clairs – tels que les symboles. 19659002] Le symbole est un nouveau type primitif, un jeton unique garanti de ne jamais entrer en conflit avec un autre symbole. En ce sens, vous pourriez considérer les symboles comme une sorte d'identificateur universel unique (19459006) UUID . Regardons comment fonctionnent les symboles et ce que nous pouvons faire avec eux

Créer de nouveaux symboles

Créer de nouveaux symboles est très simple et consiste simplement à appeler la fonction Symbol . Notez qu'il s'agit simplement d'une fonction standard et non d'un constructeur d'objet. Si vous essayez de l'appeler avec l'opérateur new vous obtiendrez une erreur Type . Chaque fois que vous appelez la fonction Symbol vous obtenez une nouvelle valeur totalement unique.

 const foo = Symbol ();
barre de const = Symbol ();

foo === bar
// <- false

Les symboles peuvent également être créés avec une étiquette, en passant une chaîne comme premier argument. L'étiquette n'affecte pas la valeur du symbole, mais est utile pour le débogage et est affichée si la méthode toString () du symbole est appelée. Il est possible de créer plusieurs symboles avec la même étiquette, mais il n'y a aucun avantage à le faire et cela conduirait probablement à de la confusion.

 let foo = Symbol ('baz');
let bar = Symbole ('baz');

foo === bar
// <- false
console.log (foo);
// <- Symbole (baz)

Que puis-je faire avec les symboles?

Les symboles peuvent remplacer les chaînes ou les entiers comme des constantes de classe / module:

 class Application {
  constructeur (mode) {
    commutateur (mode) {
      cas Application.DEV:
        // Configurer l'application pour l'environnement de développement
        Pause;
      cas Application.PROD:
        // Configurer l'application pour l'environnement de production
        Pause;
      cas par défaut:
        throw new Error ('Mode d'application invalide:' + mode);
    }
  }
}

Application.DEV = Symbole ('dev');
Application.PROD = Symbole ('prod');

// Exemple d'utilisation
const app = nouvelle application (Application.DEV);

Les chaînes et les entiers ne sont pas des valeurs uniques; des valeurs telles que le numéro 2 ou le développement de la chaîne par exemple, pourraient également être utilisées ailleurs dans le programme à des fins différentes. L'utilisation de symboles signifie que nous pouvons être plus confiants quant à la valeur fournie.

Une autre utilisation intéressante des symboles est celle des clés de propriété d'objet. Si vous avez déjà utilisé un objet JavaScript en tant que hashmap (un tableau associatif en termes PHP, ou un dictionnaire en Python) vous serez familiarisé avec l'obtention / définition des propriétés en utilisant la notation bracket:

 const données = [];

données ['name'] = 'Ted Mosby';
données ['nickname'] = 'Teddy Westside';
données ['city'] = 'New York';

En utilisant la notation des parenthèses, nous pouvons également utiliser un symbole comme clé de propriété. Il y a quelques avantages à le faire. Tout d'abord, vous pouvez être sûr que les clés basées sur des symboles ne se contracteront jamais, contrairement aux clés de chaîne, qui pourraient entrer en conflit avec des clés pour des propriétés ou méthodes existantes d'un objet. Deuxièmement, ils ne seront pas énumérés dans pour ... dans boucles, et sont ignorés par des fonctions telles que Object.keys () Object.getOwnPropertyNames () et JSON.stringify () . Cela les rend idéales pour les propriétés que vous ne souhaitez pas inclure lors de la sérialisation d'un objet.

 const user = {};
const email = Symbole ();

user.name = 'Fred';
user.age = 30;
utilisateur [email] = 'fred@example.com';

Object.keys (utilisateur);
// <- Array [ "name", "age" ]

Object.getOwnPropertyNames (utilisateur);
// <- Array [ "name", "age" ]

JSON.stringify (utilisateur);
// <- "{" name ":" Fred "," age ": 30}"

Il est à noter, cependant, que l'utilisation de symboles comme clés ne garantit pas la confidentialité. De nouveaux outils sont fournis pour vous permettre d'accéder aux clés de propriétés basées sur des symboles. Object.getOwnPropertySymbols () retourne un tableau de toutes les clés basées sur des symboles, tandis que Reflect.ownKeys () renvoie un tableau de toutes les clés, y compris les symboles.

 Object.getOwnPropertySymbols (utilisateur);
// <- Array [ Symbol() ]

Reflect.ownKeys (utilisateur)
// <- Array [ "name", "age", Symbol() ]

Symboles connus

Parce que les propriétés de clés symboliques sont effectivement invisibles au code pré-ES6, elles sont idéales pour ajouter de nouvelles fonctionnalités aux types existants de JavaScript sans casser la compatibilité ascendante. Les symboles "bien connus" sont des propriétés prédéfinies de la fonction Symbol qui sont utilisées pour personnaliser le comportement de certaines fonctions du langage et sont utilisées pour implémenter de nouvelles fonctionnalités telles que les itérateurs.

Symbol.iterator est un symbole bien connu qui est utilisé pour assigner une méthode spéciale aux objets, ce qui leur permet d'être itérés:

 const band = ['Freddy', 'Brian', 'John', 'Roger'];
const itérateur = bande [Symbol.iterator] ();

iterator.next (). value;
// <- {value: "Freddy", done: false}
iterator.next (). value;
// <- {value: "Brian", done: false}
iterator.next (). value;
// <- {value: "John", done: false}
iterator.next (). value;
// <- {value: "Roger", done: false}
iterator.next (). value;
// <- {value: undefined, done: true}

Les types intégrés Chaîne Tableau TypedArray La carte et Ensemble ont tous un default Symbol.iterator méthode qui est appelée lorsqu'une instance de l'un de ces types est utilisée dans une boucle pour ... de ou avec l'opérateur spread. Les navigateurs commencent également à utiliser la clé Symbol.iterator pour permettre à des structures DOM telles que NodeList et HTMLCollection d'être itérées de la même manière.

Le registre global

La spécification définit également un registre de symboles à l'exécution, ce qui signifie que vous pouvez stocker et récupérer des symboles dans différents contextes d'exécution, par exemple entre un document et un iFrame incorporé ou un service worker. Symbol.for (key) récupère le symbole pour une clé donnée du registre. Si aucun symbole n'existe pour la clé, une nouvelle est renvoyée. Comme vous pouvez vous y attendre, les appels suivants pour la même clé renverront le même symbole.

Symbol.keyFor (symbole) vous permet de récupérer la clé pour un symbole donné. L'appel de la méthode avec un symbole qui n'existe pas dans le registre renvoie undefined:

 const debbie = Symbol.for ('user');
const mike = Symbol.for ('utilisateur');

debbie === mike
// <- true

Symbol.keyFor (debbie);
// <- "user"

Cas d'utilisation

Il y a deux cas d'utilisation où l'utilisation de symboles procure un avantage. Un, que j'ai abordé plus tôt dans l'article, est lorsque vous voulez ajouter des propriétés "cachées" aux objets qui ne seront pas inclus lorsque l'objet est sérialisé.

Les auteurs de bibliothèque peuvent également utiliser des symboles propriétés ou méthodes sans avoir à se soucier d'écraser les clés existantes (ou d'avoir leurs clés écrasées par un autre code). Par exemple, les composants de widget (tels que les sélecteurs de date) sont souvent initialisés avec diverses options et l'état qui doit être stocké quelque part. L'attribution de l'instance du widget à une propriété de l'objet élément DOM n'est pas idéale, car cette propriété pourrait potentiellement entrer en conflit avec une autre clé. L'utilisation judicieuse d'une clé basée sur des symboles évite ce problème et garantit que votre instance de widget ne sera pas remplacée. Voir l'article du blog Mozilla Hacks ES6 en Profondeur: Symboles pour une exploration plus détaillée de cette idée

Browser Support

Si vous voulez expérimenter avec des symboles, le support navigateur classique est assez bien . Comme vous pouvez le voir, les versions actuelles de Chrome, Firefox, Microsoft Edge et Opera supportent nativement le type de symbole, avec Android 5.1 et iOS 9 sur les appareils mobiles. Il y a aussi polyfills disponibles si vous avez besoin de supporter des navigateurs plus anciens.

Conclusion

Bien que la principale raison de l'introduction de symboles semble avoir été de faciliter l'ajout de nouvelles fonctionnalités au langage sans casser code, ils ont des utilisations intéressantes. Il est intéressant pour tous les développeurs d'en avoir au moins une connaissance de base et de se familiariser avec les symboles les plus utilisés et les plus connus.




Source link