Private "Funktionen" in TypeScript

74

Ist es möglich, eine private "Funktion" (Methode) innerhalb einer TypeScript-Klasse zu erstellen? Nehmen wir an, wir haben die folgende Person.tsTypeScript-Datei:

class Person {
    constructor(public firstName: string, public lastName: string) {
    }

    public shout(phrase: string) {
        alert(phrase);
    }

    private whisper(phrase: string) {
        console.log(phrase);
    }
}

Was beim Kompilieren in Folgendes umgewandelt wird:

var Person = (function () {
    function Person(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    Person.prototype.shout = function (phrase) {
        alert(phrase);
    };
    Person.prototype.whisper = function (phrase) {
        console.log(phrase);
    };
    return Person;
})();

Beobachtungen

Ich hatte erwartet, dass die whisperFunktion innerhalb des Verschlusses deklariert wird, aber nicht auf dem Prototyp? Im Wesentlichen macht dies die whisperFunktion öffentlich, wenn sie kompiliert wird?

Richard
quelle
1
Mögliches Duplikat von privaten TypeScript-Mitgliedern
Jude Fisher

Antworten:

88

Öffentliche / private Keywords von TypeScript gelten nur für die Art und Weise, wie TypeScript Ihren Code überprüft. Sie haben keine Auswirkungen auf die JavaScript-Ausgabe.

Gemäß der Sprachspezifikation (S. 9-10):

Private Sichtbarkeit ist ein Konstrukt zur Entwurfszeit. Es wird während der statischen Typprüfung erzwungen, impliziert jedoch keine Laufzeiterzwingung. ... TypeScript erzwingt die Kapselung der Implementierung in Klassen zur Entwurfszeit (durch Einschränkung der Verwendung privater Mitglieder), kann jedoch die Kapselung zur Laufzeit nicht erzwingen, da zur Laufzeit auf alle Objekteigenschaften zugegriffen werden kann. Zukünftige Versionen von JavaScript enthalten möglicherweise private Namen, die die Laufzeitdurchsetzung privater Mitglieder ermöglichen

Dies wurde hier bereits gefragt und beantwortet: https://stackoverflow.com/a/12713869/1014822

Update: Diese alte Antwort erhält immer noch eine Menge Verkehr. Es ist also erwähnenswert, dass zusätzlich zu dem obigen Link für Sprachspezifikationen öffentliche, private und (jetzt) ​​geschützte Mitglieder im Kapitel zum TypeScript- Handbuch über Klassen ausführlich behandelt werden.

Die Implementierung von ES Private Fields für das Update 2018 ist jetzt ein zukünftiges Element in der TypeScript- RoadMap, obwohl die Diskussion darauf hinweist , dass dies eine parallele Hard-Private-Option ist und kein Ersatz für die aktuelle Soft-Private-Implementierung.

2020 Update Runtime Private Felder mit dem #Operator wurden ab TS 3.8 implementiert. Es gibt eine gute Diskussion darüber , wie sie funktionieren und wie sie sich unterscheiden von Kompilierung-Felder mit dem privateStichwort auf Stackoverflow hier .

Private Methoden haben Stufe 3 der TC39-Arbeitsgruppe erreicht. Die Funktion ist derzeit in der aktiven Diskussion für Typoskript, zum Beispiel hier .

Jude Fisher
quelle
1
Seltsam, dass das Kapitel über Funktionen diesbezüglich nichts sagt.
StingyJack
9

In Javascript (im Gegensatz zu TypeScript) können Sie keine private "Member" -Funktion haben.

Wenn Sie eine private Funktion im Abschluss definieren, können Sie sie nicht als Instanzmethode für eine Instanz Ihrer Klasse aufrufen.

Wenn Sie dies wünschen, verschieben Sie einfach die TypeScript-Funktionsdefinition außerhalb des Klassenkörpers.

SLaks
quelle
Hmm, ich denke da wo das var self = this;zutrifft? Ist es möglich, eine Funktion innerhalb eines Abschlusses zu deklarieren, die nicht explizit auf Instanzinformationen zugreift?
Richard
2
@ Richard: Nein; var self = thishat damit nichts zu tun. Der Punkt ist, dass es keine Möglichkeit gibt, instance.method()nur in Ihrem Verschluss zu arbeiten.
SLaks
Sicher; Es ist jedoch möglich, einfach method()aus einer (öffentlichen) Instanzmethode heraus aufzurufen , nicht wahr?
Richard
1
Ja, aber es wird nichts mit der Klasse zu tun haben. (obwohl Sie thisals Parameter akzeptieren können )
SLaks
Dies ist möglich, aber jeder Aufruf einer privaten Methode müsste mit apply () oder call () mit der Instanz "this" erfolgen.
Nomaed
0

Sie können private Klassenvariablen und -funktionen in TypeScript / Webpack und sogar in den neuesten Google Chrome-Versionen nativ verwenden. Fügen Sie einfach ein #vor dem Namen hinzu. Siehe hier .

MyClass{

  #privateMember: Number = 4 

  #privateMethod() {
      this.#privateMember = 3
  }
}
air5
quelle