Membri privati ​​di TypeScript

Sto esaminando l’implementazione di membri privati ​​in TypeScript, e trovo un po ‘di confusione. Intellisense non consente di accedere a membri privati, ma in puro JavaScript, è tutto lì. Questo mi fa pensare che TS non implementa correttamente i membri privati. qualche idea?

class Test{ private member: any = "private member"; } alert(new Test().member); 

Proprio come per il controllo del tipo, la privacy dei membri viene applicata solo all’interno del compilatore.

Una proprietà privata è implementata come una proprietà normale e il codice esterno alla class non è autorizzato ad accedervi.

Per rendere qualcosa di veramente privato all’interno della class, non può essere un membro della class, sarebbe una variabile locale creata all’interno di un ambito di funzione all’interno del codice che crea l’object. Ciò significherebbe che non puoi accedervi come un membro della class, cioè utilizzando la parola chiave this .

JavaScript supporta variabili private.

 function MyClass() { var myPrivateVar = 3; this.doSomething = function() { return myPrivateVar++; } } 

In TypeScript questo sarebbe express in questo modo:

 class MyClass { doSomething: () => number; constructor() { var myPrivateVar = 3; this.doSomething = function () { return myPrivateVar++; } } } 

MODIFICARE

Questo approccio dovrebbe essere usato solo in modo SPARINGLY dove è assolutamente necessario. Ad esempio se è necessario memorizzare temporaneamente una password nella cache.

Ci sono costi di prestazioni per l’utilizzo di questo modello (irrilevante di Javascript o Typescript) e dovrebbero essere utilizzati solo dove assolutamente necessario.

Una volta che il supporto per WeakMap è più ampiamente disponibile, qui c’è una tecnica interessante illustrata nell’Esempio # 3.

Permette di dati privati ​​ed evita i costi delle prestazioni dell’esempio di Jason Evans consentendo ai dati di essere accessibili da metodi di prototipo invece che da metodi di istanza.

La pagina MDN WeakMap collegata elenca il supporto del browser su Chrome 36, Firefox 6.0, IE 11, Opera 23 e 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)(); } } } 

Grazie a Sean Feldman per il link alla discussione ufficiale su questo tema – vedi la sua risposta al link.

Ho letto la discussione a cui si è collegato, ed ecco un riassunto dei punti chiave:

  • Suggerimento: proprietà private nel costruttore
    • problemi: imansible accedere dalle funzioni del prototipo
  • Suggerimento: metodi privati ​​nel costruttore
    • problemi: come con le proprietà, inoltre si perde il vantaggio in termini di prestazioni di creare una funzione una volta per class nel prototipo; invece si crea una copia della funzione per ogni istanza
  • Suggerimento: aggiungi la scheda tecnica per l’accesso astratto alla proprietà e aumenta la visibilità
    • problemi: overhead delle prestazioni importanti; TypeScript è progettato per applicazioni di grandi dimensioni
  • Suggerimento: TypeScript racchiude già le definizioni del metodo costruttore e prototipo in una chiusura; metti i metodi e le proprietà private lì
    • problemi nel mettere proprietà private in quella chiusura: diventano variabili statiche; non ce n’è uno per istanza
    • problemi nel mettere metodi privati ​​in quella chiusura: non hanno accesso a this senza una sorta di soluzione alternativa
  • Suggerimento: manipola automaticamente i nomi delle variabili private
    • argomenti contrari: è una convenzione di denominazione, non una costruzione di linguaggio. Mangle te stesso
  • Suggerimento: @private metodi privati ​​con @private modo che i minisatori riconoscano che l’annotazione può effettivamente ridurre i nomi dei metodi
    • Nessun argomento contrario significativo a questo

Contro-argomenti generali per l’aggiunta del supporto per la visibilità nel codice emesso:

  • il problema è che JavaScript stesso non ha modificatori di visibilità – questo non è un problema di TypeScript
  • c’è già un modello stabilito nella comunità JavaScript: prefisso proprietà private e metodi con un carattere di sottolineatura, che dice “procedi a tuo rischio”
  • quando i progettisti di TypeScript hanno affermato che proprietà e metodi veramente privati ​​non sono “possibili”, intendevano “non ansible in base ai nostri vincoli di progettazione”, in particolare:
    • Il JS emesso è idiomatico
    • Boilerplate è minimo
    • Nessun overhead aggiuntivo rispetto al normale JS OOP

In TypeScript, le funzioni private sono accessibili solo all’interno della class. Piace

inserisci la descrizione dell'immagine qui

E mostrerà un errore quando si tenta di accedere a un membro privato. Ecco l’esempio:

inserisci la descrizione dell'immagine qui

Nota: andrà bene con javascript ed entrambe le funzioni sono accessibili all’esterno.