Je regarde l'implémentation de membres privés dans TypeScript, et je trouve cela un peu déroutant. Intellisense ne permet pas d'accéder à un membre privé, mais en JavaScript pur, tout y est. Cela me fait penser que TS n'implémente pas correctement les membres privés. Des pensées?
class Test{
private member: any = "private member";
}
alert(new Test().member);
Comme pour la vérification de type, la confidentialité des membres est uniquement appliquée au sein du compilateur.
Une propriété privée est implémentée en tant que propriété standard et le code en dehors de la classe n'est pas autorisé à y accéder.
Pour rendre quelque chose de vraiment privé dans la classe, il ne peut s'agir d'un membre de la classe, mais d'une variable locale créée dans une portée de fonction dans le code qui crée l'objet. Cela signifierait que vous ne pouvez pas y accéder comme un membre de la classe, c’est-à-dire en utilisant le mot-clé this
.
JavaScript supporte les variables privées.
function MyClass() {
var myPrivateVar = 3;
this.doSomething = function() {
return myPrivateVar++;
}
}
Dans TypeScript, cela serait exprimé ainsi:
class MyClass {
doSomething: () => number;
constructor() {
var myPrivateVar = 3;
this.doSomething = function () {
return myPrivateVar++;
}
}
}
EDIT
Cette approche ne devrait être utilisée que AVEC PARCIMONIE où elle est absolument nécessaire. Par exemple, si vous devez mettre en cache un mot de passe temporairement.
L'utilisation de ce modèle entraîne des coûts de performance (non liés à Javascript ou à TypeScript) et ne doit être utilisé qu'en cas d'absolue nécessité.
Une fois que le support de WeakMap est plus largement disponible, il existe une technique intéressante détaillée dans l'exemple n ° 3 ici .
Il permet de stocker des données privées ET évite les coûts de performance de Jason Evans en rendant les données accessibles à partir de méthodes prototypes au lieu de méthodes à instance unique.
La page liée MDN WeakMap indique la prise en charge du navigateur à Chrome 36, Firefox 6.0, IE 11, Opera 23 et Safari 7.1.
let _counter = new WeakMap();
let _action = new WeakMap();
class Countdown {
constructor(counter, action) {
_counter.set(this, counter);
_action.set(this, action);
}
decrement() {
let counter = _counter.get(this);
if (counter < 1) return;
counter--;
_counter.set(this, counter);
if (counter === 0) {
_action.get(this)();
}
}
}
Merci à Sean Feldman pour le lien vers la discussion officielle sur cette question - voir sa réponse pour le lien.
J'ai lu la discussion à laquelle il a lié, et voici un résumé des points clés:
this
sans solution de contournement@private
donc les minificateurs qui reconnaissent que l’annotation peuvent effectivement réduire les noms de méthodes Contre-arguments globaux pour l'ajout de la prise en charge de la visibilité dans le code émis:
Je réalise que cette discussion est plus ancienne, mais il pourrait toujours être utile de partager ma solution au problème des variables et méthodes supposément privées dans un TypeScript "filtrant" dans l'interface publique de la classe JavaScript compilée.
Pour moi, ce problème est purement esthétique, c’est-à-dire qu’il s’agit de l’encombrement visuel lorsqu’une variable d’instance est affichée dans DevTools. Ma solution consiste à regrouper les déclarations privées dans une autre classe, qui est ensuite instanciée dans la classe principale et affectée à une variable private
(mais toujours visible publiquement dans JS) avec un nom comme __
(double trait de soulignement).
Exemple:
class Privates {
readonly DEFAULT_MULTIPLIER = 2;
foo: number;
bar: number;
someMethod = (multiplier: number = this.DEFAULT_MULTIPLIER) => {
return multiplier * (this.foo + this.bar);
}
private _class: MyClass;
constructor(_class: MyClass) {
this._class = _class;
}
}
export class MyClass {
private __: Privates = new Privates(this);
constructor(foo: number, bar: number, baz: number) {
// assign private property values...
this.__.foo = foo;
this.__.bar = bar;
// assign public property values...
this.baz = baz;
}
baz: number;
print = () => {
console.log(`foo=${this.__.foo}, bar=${this.__.bar}`);
console.log(`someMethod returns ${this.__.someMethod()}`);
}
}
let myClass = new MyClass(1, 2, 3);
Lorsque l'instance myClass
est affichée dans DevTools, au lieu de voir tous ses membres "privés" entremêlés avec des membres véritablement publics (qui peuvent être très visuellement désordonnés dans du code réel refactorisé correctement), vous les voyez parfaitement regroupés à l'intérieur du code. s'est effondré __
propriété: