Typescript privat membri

voturi
76

Mă uit la punerea în aplicare a membrilor privați dactilografiat, și mi se pare un pic confuz. IntelliSense nu permite să acceseze membru privat, dar pur JavaScript, e tot acolo. Acest lucru mă face să cred că TS nu pune în aplicare în mod corect privat membri. Orice gânduri?

class Test{
  private member: any = private member;
}
alert(new Test().member);
Întrebat 03/10/2012 la 18:24
sursa de către utilizator
În alte limbi...                            


7 răspunsuri

voturi
68

La fel ca și cu verificarea de tip, viața privată a membrilor sunt puse în aplicare numai în cadrul compilator.

O proprietate privată este pus în aplicare ca o proprietate regulat, și codul din afara clasei nu îi este permis să-l acceseze.

Pentru a face ceva cu adevărat privat în interiorul clasei, nu poate fi un membru al clasei, ar fi o variabilă locală , creată în interiorul unui domeniu de aplicare funcții în interiorul codul care creează obiectul. Asta ar însemna că nu se poate accesa ca un membru al clasei, adică folosind thiscuvântul cheie.

Publicat 03/10/2012 la 18:36
sursa de către utilizator

voturi
33

JavaScript nu acceptă variabile private.

function MyClass() {
    var myPrivateVar = 3;

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

Dactilografiat acest lucru ar fi exprimat astfel:

class MyClass {

    doSomething: () => number;

    constructor() {
        var myPrivateVar = 3;

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

EDITAȚI | ×

Această abordare ar trebui să fie utilizat numai cu moderație în cazul în care este absolut necesar. De exemplu , în cazul în care aveți nevoie pentru a cache temporar o parolă.

Există costuri de performanță în utilizarea acestui model (irelevant de Javascript sau typescript) și trebuie utilizat numai în cazul în care este absolut necesar.

Publicat 06/06/2014 la 17:01
sursa de către utilizator

voturi
11

Odată ce sprijinul pentru WeakMap este mai disponibil pe scară largă există o tehnică interesantă este detaliat în exemplul # 3 aici .

Acesta permite datelor private și evită costurile de performanță de exemplu, Jason Evans, permițând ca datele să fie accesibile din metodele de prototip în loc de metode de instanță numai.

Legat MDN WeakMap liste pagina de suport browser-ul de la Chrome 36, Firefox 6.0, IE 11, Opera 23 și 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)();
    }
  }
}
Publicat 10/04/2016 la 04:23
sursa de către utilizator

voturi
3

Datorită Sean Feldman pentru link - ul la discuția oficială cu privire la această problemă - a se vedea răspunsul său pentru link - ul.

Am citit discuția legată de el, și aici este un rezumat al punctelor - cheie:

  • Sugestie: proprietăți particulare în constructor
    • probleme: nu pot avea acces la funcții prototip
  • Sugestie: Metode private în constructor
    • Probleme: La fel ca cu proprietăți, plus pierde beneficiul performanța de a crea o funcție de o dată pe clasă în prototip; în schimb să creați o copie a funcției pentru fiecare instanță
  • Sugestie: adăugați șabloane pentru accesul de proprietate abstract și pune în aplicare vizibilitatea
    • probleme: aeriene majore de performanță; Typescript este proiectat pentru aplicații mari
  • Sugestie: typescript înfășoară deja constructor și metoda de prototip definiții într - o închidere; pune metode private și proprietăți acolo
    • probleme cu punerea proprietăți private , în această închidere: ele devin variabile statice; nu există una pentru fiecare instanță
    • probleme cu punerea metode private în acest închidere: ei nu au acces la thisfără un fel de workaround
  • Sugestie: mangle automat numele variabilelor privat
    • contra argumente: că este o convenție de denumire, nu este o construcție de limbaj. Mangle - l singur
  • Sugestie: Annotate metode private cu @privateastfel minifiers care recunosc că adnotare poate minify în mod eficient numele metodelor
    • Nu există argumente contra semnificative la aceasta

În general contra-argumente pentru adăugarea de suport de vizibilitate în codul emis:

  • problema este că JavaScript în sine nu are modificatori de vizibilitate - acest lucru nu este problema lui typescript
  • există deja un model stabilit în comunitatea JavaScript: proprietăți particulare și prefix metode cu un caracter de subliniere, care spune: „Continuați pe propriul risc“
  • când designerii typescript a spus că proprietățile cu adevărat private și metode nu sunt „posibile“, au însemnat „nu este posibil în funcție de constrângerile noastre de proiectare“, în special:
    • JS este emis idiomatic
    • Boilerplate este minimă
    • Nu aeriene suplimentare față de normal JS OOP
Publicat 06/10/2016 la 14:51
sursa de către utilizator

voturi
2

Dactilografiat funcții private sunt accesibile numai în interiorul clasei. Ca

introduceți descrierea imaginii aici

Și va afișa o eroare atunci când încercați să accesați un membru privat. Iată exemplul:

introduceți descrierea imaginii aici

Notă: Va fi bine cu JavaScript și ambele funcții sunt accesibile din exterior.

Publicat 15/07/2016 la 07:33
sursa de către utilizator

voturi
1

Îmi dau seama că aceasta este o discuție mai veche, dar ar putea fi încă utilă pentru a partaja soluția mea la problema variabilelor presupuse private și metode într-o mașină de scris „scurgerea“ afară, în interfața publică a clasei JavaScript compilat.

Pentru mine această problemă este pur cosmetic, adică este vorba de dezordine vizual atunci când o variabilă instanță este vizualizat în DevTools. Fix mea este de declarații private de grup împreună într -o altă clasă , care este apoi instanțiat în clasa principală și atribuite unui private(dar încă vizibile în mod public în JS) variabilă cu un nume de genul __(subliniere dublă).

Exemplu:

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

În cazul în care myClassinstanța este vizualizat în DevTools, în loc să vadă toți membrii săi „private“ cu adevărat cele amestecate publice (care se poate obține foarte vizual dezordonat în refactored corect codul de viața reală) pe care le vezi frumos grupate în interiorul prăbușită __proprietatea:

introduceți descrierea imaginii aici

Publicat 14/09/2018 la 22:12
sursa de către utilizator

voturi
0

Mulți oameni susțin acest lucru nu este posibil din cauza limitărilor în JavaScript. Aș spune că e limitări în creativitatea dezvoltatorilor JavaScript.

Sunt în curs de dezvoltare o bibliotecă chiar acum , care permite membrilor succesorale și private protejate de clase, precum și interfețe, etc numit ClassJS. Verifică - l aici pe GitHub .

Publicat 12/04/2017 la 01:06
sursa de către utilizator

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