Cas d'utilisation: - #
champs privés
Préface:
Confidentialité à la compilation et à l' exécution
#
-Les champs privés fournissent une confidentialité au moment de la compilation et de l' exécution, qui n'est pas "piratable". C'est un mécanisme pour empêcher l'accès à un membre de l'extérieur du corps de classe de quelque manière directe .
class A {
#a: number;
constructor(a: number) {
this.#a = a;
}
}
let foo: A = new A(42);
foo.#a; // error, not allowed outside class bodies
(foo as any).#bar; // still nope.
Héritage de classe sécurisé
#
-Les champs privés ont une portée unique. Les hiérarchies de classes peuvent être implémentées sans écraser accidentellement des propriétés privées de noms égaux.
class A {
#a = "a";
fnA() { return this.#a; }
}
class B extends A {
#a = "b";
fnB() { return this.#a; }
}
const b = new B();
b.fnA(); // returns "a" ; unique property #a in A is still retained
b.fnB(); // returns "b"
Le compilateur TS émet heureusement une erreur, lorsque les private
propriétés risquent d'être écrasées (voir cet exemple ). Mais en raison de la nature d'une fonctionnalité au moment de la compilation, tout est encore possible au moment de l'exécution, étant donné que les erreurs de compilation sont ignorées et / ou le code JS émis est utilisé.
Bibliothèques externes
Les auteurs de bibliothèque peuvent refactoriser les #
identifiants privés sans provoquer de changement majeur pour les clients. Les utilisateurs de la bibliothèque de l'autre côté sont protégés contre l'accès aux champs internes.
L'API JS omet les #
champs privés
Les fonctions et méthodes JS intégrées ignorent les #
champs privés. Cela peut entraîner une sélection de propriétés plus prévisible au moment de l'exécution. Exemples: Object.keys
, Object.entries
, JSON.stringify
, for..in
boucle et autres ( exemple de code , voir aussi Matt Bierner réponse ):
class Foo {
#bar = 42;
baz = "huhu";
}
Object.keys(new Foo()); // [ "baz" ]
Cas d'utilisation: private
mot - clé
Préface:
Accès à l'API et à l'état de la classe interne (confidentialité au moment de la compilation uniquement)
private
les membres d'une classe sont des propriétés classiques au moment de l'exécution. Nous pouvons utiliser cette flexibilité pour accéder à l'API interne de classe ou à l'état de l'extérieur. Afin de satisfaire les vérifications du compilateur, des mécanismes tels que les assertions de type, l'accès aux propriétés dynamiques ou @ts-ignore
peuvent être utilisés entre autres.
Exemple avec assertion de type ( as
/ <>
) et any
affectation de variable typée:
class A {
constructor(private a: number) { }
}
const a = new A(10);
a.a; // TS compile error
(a as any).a; // works
const casted: any = a; casted.a // works
TS permet même un accès dynamique aux propriétés d'un private
membre avec un hayon :
class C {
private foo = 10;
}
const res = new C()["foo"]; // 10, res has type number
Où l'accès privé peut-il avoir un sens? (1) des tests unitaires, (2) des situations de débogage / journalisation ou (3) d'autres scénarios de cas avancés avec des classes internes au projet (liste ouverte).
L'accès aux variables internes est un peu contradictoire - sinon vous ne les auriez pas faites private
en premier lieu. Pour donner un exemple, les tests unitaires sont supposés être des boîtes noires / grises avec des champs privés cachés comme détails d'implémentation. En pratique cependant, il peut y avoir des approches valables d'un cas à l'autre.
Disponible dans tous les environnements ES
Les private
modificateurs TS peuvent être utilisés avec toutes les cibles ES. #
-Les champs privés ne sont disponibles que pour target
ES2015
/ ES6
ou plus. Dans ES6 +, WeakMap
est utilisé en interne comme implémentation de niveau inférieur (voir ici ). Les #
champs natifs- privés nécessitent actuellement target
esnext
.
Cohérence et compatibilité
Les équipes peuvent utiliser des directives de codage et des règles de linter pour imposer l'utilisation de private
comme seul modificateur d'accès. Cette restriction peut aider à la cohérence et éviter toute confusion avec la #
notation de champ privé d'une manière rétrocompatible.
Si nécessaire, les propriétés des paramètres (raccourci d'affectation du constructeur) sont un bouchon d'exposition. Ils ne peuvent être utilisés qu'avec des private
mots clés et il n'est pas encore prévu de les implémenter pour les #
champs privés.
Autres raisons
private
peut fournir de meilleures performances d'exécution dans certains cas de mise à niveau inférieur (voir ici ).
- Jusqu'à présent, aucune méthode de classe privée dure n'est disponible dans TS.
- Certaines personnes préfèrent la
private
notation par mots clés 😊.
Remarque sur les deux
Les deux approches créent une sorte de type nominal ou de marque au moment de la compilation.
class A1 { private a = 0; }
class A2 { private a = 42; }
const a: A1 = new A2();
// error: "separate declarations of a private property 'a'"
// same with hard private fields
En outre, les deux autorisent l'accès inter-instances: une instance de classe A
peut accéder aux membres privés d'autres A
instances:
class A {
private a = 0;
method(arg: A) {
console.log(arg.a); // works
}
}
Sources