Dattiloscritto soci privati

voti
76

Sto guardando realizzazione di soci privati ​​a macchina, e lo trovo un po 'di confusione. Intellisense non permette di membro privato di accesso, ma in puro JavaScript, è tutto lì. Questo mi fa pensare che TS non implementa correttamente soci privati. qualche idea?

class Test{
  private member: any = private member;
}
alert(new Test().member);
È pubblicato 03/10/2012 alle 18:24
fonte dall'utente
In altre lingue...                            


7 risposte

voti
68

Proprio come con il controllo di tipo, la privacy dei membri vengono applicate solo all'interno del compilatore.

Una proprietà privata è implementato come una proprietà regolare, e il codice di fuori della classe non è permesso di accedervi.

Per fare qualcosa di veramente privato all'interno della classe, non può essere un membro della classe, sarebbe una variabile locale creata all'interno di un ambito di funzioni all'interno del codice che crea l'oggetto. Ciò significherebbe che non è possibile accedere come un membro della classe, vale a dire utilizzando la thisparola chiave.

Risposto il 03/10/2012 a 18:36
fonte dall'utente

voti
33

JavaScript supporta variabili private.

function MyClass() {
    var myPrivateVar = 3;

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

A macchina questo sarebbe espresso in questo modo:

class MyClass {

    doSomething: () => number;

    constructor() {
        var myPrivateVar = 3;

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

MODIFICARE

Questo approccio deve essere utilizzato solo con parsimonia in cui è assolutamente necessario. Per esempio, se avete bisogno di memorizzare nella cache temporanea di una password.

Ci sono costi di prestazioni di utilizzare questo schema (irrilevante di Javascript o tipografico) e dovrebbero essere utilizzati solo se assolutamente necessario.

Risposto il 06/06/2014 a 17:01
fonte dall'utente

voti
11

Una volta che il supporto per WeakMap è più ampiamente disponibili v'è una tecnica interessante dettagliato nel esempio # 3 qui .

Permette di dati privati ​​ed evita i costi di prestazioni di Jason Evans esempio consentendo che i dati siano accessibili dai metodi prototipo, invece di metodi di istanza solo.

La pagina elenca il supporto del browser collegato MDN WeakMap a 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)();
    }
  }
}
Risposto il 10/04/2016 a 04:23
fonte dall'utente

voti
3

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

Ho letto la discussione ha legato a, e ecco una sintesi dei punti chiave:

  • Suggerimento: proprietà private a costruttore
    • problemi: non possono accedere dalle funzioni prototipo
  • Suggerimento: metodi privati in costruttore
    • problemi: come con le proprietà, più si perde il beneficio di prestazioni di creazione di una funzione una volta per classe nel prototipo; invece di creare una copia della funzione per ogni istanza
  • Suggerimento: aggiungere boilerplate per accedere alla proprietà astratta e far rispettare la visibilità
    • problemi: grandi investimenti prestazioni; Dattiloscritto è stato progettato per applicazioni di grandi dimensioni
  • Suggerimento: dattiloscritto avvolge già le definizioni di costruttore e il metodo prototipo in una chiusura; mettere i metodi e le proprietà private lì
    • problemi con la messa in proprietà private che la chiusura: diventano variabili statiche; Non v'è uno per esempio
    • problemi con la messa metodi privati in quella di chiusura: non hanno accesso ai thissenza una sorta di soluzione
  • Suggerimento: mangle automaticamente i nomi delle variabili private
    • argomenti contrari: questa è una convenzione di denominazione, non un costrutto del linguaggio. Mangle da soli
  • Suggerimento: Annota i metodi privati con @privatecosì minifiers che riconoscono che l'annotazione può efficacemente minify i nomi dei metodi
    • Non ci sono argomenti contrari significativi per questo

contro-argomentazioni globale per aggiungere il supporto visibilità in codice emesso:

  • il problema è che JavaScript per sé non ha modificatori di visibilità - questo non è un problema di dattiloscritto
  • c'è già un modello stabilito nella comunità JavaScript: prefisso proprietà private e metodi con un carattere di sottolineatura, che dice "procedono a proprio rischio"
  • quando i progettisti dattiloscritto ha detto che le proprietà ei metodi veramente privati ​​non sono "possibili", che significava "non è possibile sotto i nostri vincoli di progettazione", in particolare:
    • Il JS emessa è idiomatica
    • Boilerplate è minima
    • Nessun overhead aggiuntivo rispetto al normale JS OOP
Risposto il 06/10/2016 a 14:51
fonte dall'utente

voti
2

A macchina funzioni private sono accessibili solo all'interno della classe. Piace

entrare descrizione dell'immagine qui

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

entrare descrizione dell'immagine qui

Nota: Sarà bene con javascript e sia la funzione sono accessibili dall'esterno.

Risposto il 15/07/2016 a 07:33
fonte dall'utente

voti
1

Mi rendo conto che è una discussione più vecchio ma potrebbe ancora essere utile per condividere la mia soluzione al problema delle variabili apparentemente private e metodi in un dattiloscritto "fuoriuscita" fuori nella interfaccia pubblica della classe JavaScript compilato.

Per me la questione è puramente cosmetico, vale a dire che è tutta una questione di ingombro visivo quando una variabile di istanza viene visualizzato in DevTools. La mia soluzione è quella di raggruppare le dichiarazioni private insieme all'interno di un'altra classe che viene poi creata un'istanza nella classe principale e assegnato a una private(ma ancora visibile al pubblico in JS) variabile con un nome simile __(doppia sottolineatura).

Esempio:

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);

Quando l' myClassistanza viene visualizzato in DevTools, invece di vedere tutti i suoi membri "privati" mescolati con quelli veramente pubbliche (che può diventare molto disordinato visivamente in modo corretto refactoring del codice di vita reale) li vedi ordinatamente raggruppati all'interno della crollato __immobile:

entrare descrizione dell'immagine qui

Risposto il 14/09/2018 a 22:12
fonte dall'utente

voti
0

Molte persone sostengono che questo non è possibile a causa delle limitazioni in JavaScript. Direi che è limitazioni nella creatività sviluppatori JavaScript.

Sto sviluppando una libreria in questo momento che permette private e protette membri ereditabili di classi, così come le interfacce, ecc chiamato ClassJS. Check it out qui su GitHub .

Risposto il 12/04/2017 a 01:06
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more