Loggfila private medlemmer

stemmer
83

Jeg ser på gjennomføringen av private medlemmer i maskinskrevet manuskript, og jeg synes det er litt forvirrende. IntelliSense tillater ikke tilgang til private medlem, men i ren Javascript, alt er der. Dette gjør at jeg tror at TS ikke implementerer private medlemmer riktig. noen tanker?

class Test{
  private member: any = private member;
}
alert(new Test().member);
Publisert på 03/10/2012 klokken 17:24
kilden bruker
På andre språk...                            


7 svar

stemmer
76

Akkurat som med den type kontroll, er personvernet til medlemmene bare håndheves i kompilatoren.

En privat eiendom er implementert som en vanlig eiendom, og kode utenfor klassen er ikke tilgang til det.

For å gjøre noe helt privat inne i klassen, kan det ikke være medlem av klassen, ville det være en lokal variabel opprettet inne i en funksjon omfang inne i koden som skaper objektet. Det ville bety at du ikke får tilgang til det som et medlem av klassen, det vil si ved hjelp av thissøkeordet.

Svarte 03/10/2012 kl. 17:36
kilden bruker

stemmer
34

Javascript støtter private variabler.

function MyClass() {
    var myPrivateVar = 3;

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

I Loggfila dette ville bli uttrykt slik:

class MyClass {

    doSomething: () => number;

    constructor() {
        var myPrivateVar = 3;

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

REDIGERE

Denne tilnærmingen bør bare brukes sparsomt der det er absolutt nødvendig. For eksempel hvis du trenger å cache passord midlertidig.

Det er ytelses kostnader med å bruke dette mønsteret (irrelevant på Javascript eller maskinskrevet manuskript), og bør bare brukes når det er absolutt nødvendig.

Svarte 06/06/2014 kl. 16:01
kilden bruker

stemmer
12

Når støtte for WeakMap er mer allment tilgjengelig er det en interessant teknikk beskrevet i eksempel # 3 her .

Det gjør det mulig for private data og unngår ytelses kostnadene ved Jason Evans eksempel ved at dataene skal være tilgjengelig fra prototype metoder i stedet for bare instansmetoder.

Det koblede nettleser støtter MDN WeakMap sidelister på Chrome 36, Firefox 6.0, IE 11, Opera 23 og 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)();
    }
  }
}
Svarte 10/04/2016 kl. 04:23
kilden bruker

stemmer
3

Takk til Sean Feldman for linken til den offisielle diskusjon om dette spørsmålet - se hans svar for koblingen.

Jeg leste diskusjonen han linket til, og her er en oppsummering av de viktigste punktene:

  • Forslag: private eiendommer i konstruktør
    • problemer: får ikke tilgang fra prototype funksjoner
  • Forslag: private metoder i konstruktør
    • problemer: samme som med egenskaper, pluss at du mister ytelse fordelen med å lage en funksjon en gang per klasse i prototypen; stedet du oppretter en kopi av funksjonen for hver forekomst
  • Forslag: legge tekst til abstrakt eiendom tilgang og håndheve synlighet
    • problemer: større ytelse overhead; Loggfila er designet for store programmer
  • Forslag: maskinskrevet manuskript brytes allerede konstruktøren og Prototypemetoden definisjonene i en lukning; sette private metoder og egenskaper det
    • problemer med å sette private eiendommer i at nedleggelse: de blir statiske variabler; det er ikke en per forekomst
    • problemer med å sette private metoder i at nedleggelse: de ikke har tilgang til thisuten noen form for løsning
  • Forslag: automatisk mangle de private variabelnavn
    • motargumenter: det er en navnekonvensjon, ikke et språk konstruere. Mangle det selv
  • Forslag: Kommentere private metoder med @privateså minifiers som anerkjenner at merknaden effektivt kan minify de metodenavn
    • Ingen vesentlige motargumenter til dette

Totalt motargumenter til å legge synlighet støtte slippes kode:

  • problemet er at Java selv ikke har sikt modifikatorer - dette er ikke Loggfila problem
  • Det er allerede et etablert mønster i Javascript samfunnet: prefiks private eiendommer og metoder med en understrekning, som sier "fortsette på egen risiko"
  • når Loggfila designere sa som virkelig private eiendommer og metoder er ikke "mulig", mente de "ikke mulig under våre design begrensninger", spesielt:
    • Den utsendte JS er idiomatisk
    • Tekst er minimal
    • Ingen ekstra overhead i forhold til normal JS OOP
Svarte 06/10/2016 kl. 14:51
kilden bruker

stemmer
2

I Loggfila fellesfunksjoner er bare tilgjengelige i klassen. Som

skriv bildebeskrivelse her

Og det vil vise en feilmelding når du prøver å få tilgang til en privat medlem. Her er et eksempel:

skriv bildebeskrivelse her

Merk: Det vil være fint med javascript, og både funksjon er tilgjengelig utenfor.

Svarte 15/07/2016 kl. 07:33
kilden bruker

stemmer
1

Jeg skjønner at dette er en eldre diskusjon, men det kan likevel være nyttig å dele min løsning på problemet med de angivelig private variabler og metoder i en Loggfila "lekker" ut i det offentlige grensesnittet til kompilert Javascript klassen.

For meg er dette problemet er rent kosmetisk, det vil si det handler om det visuelle rot når en instansvariabel er sett i DevTools. Min løsning er å gruppere private erklæringer sammen inne i en annen klasse som deretter startes i hovedklassen og tildelt en private(men fortsatt offentlig synlig i JS) variabel med et navn som __(dobbel understrek).

Eksempel:

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år myClassforekomsten er sett i DevTools, i stedet for å se alle sine "private" medlemmer blandet med virkelig offentlige de (som kan få svært visuelt rotete i riktig refactored real-life code) du ser dem pent gruppert inne kollapset __eiendom:

skriv bildebeskrivelse her

Svarte 14/09/2018 kl. 22:12
kilden bruker

stemmer
0

Mange hevder dette ikke er mulig på grunn av begrensninger i Javascript. Jeg vil si det er begrensninger i Javascript-utviklernes kreativitet.

Jeg utvikler et bibliotek akkurat nå som gjør at private og beskyttet arvbare medlemmer av klasser, samt grensesnitt, etc. kalt ClassJS. Sjekk det ut her på GitHub .

Svarte 12/04/2017 kl. 01:06
kilden bruker

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