Privata "funktioner" i TypeScript
Är det möjligt att skapa en privat "funktion" (metod) inom en TypeScript-klass? Låt oss anta att vi har följande Person.ts TypeScript-fil:
class Person {
constructor(public firstName: string, public lastName: string) {
}
public shout(phrase: string) {
alert(phrase);
}
private whisper(phrase: string) {
console.log(phrase);
}
}
Vilket när det kompileras omvandlas till följande:
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;
})();
Observationer
Jag förväntade mig att whisper-funktionen skulle deklareras inom stängningen, men inte på prototypen? I huvudsak gör detta att whisper-funktionen blir offentlig när den kompileras?
Svar #1
Uppdatering. Privata metoder som använder # är nu implementerade. Se här: https://github.com/microsoft/TypeScript/pull/42458
--
TypeScript public/private-nyckelord gäller bara för hur TypeScript kontrollerar din kod - de har ingen effekt på JavaScript-utdata.
Enligt språkspecifikationen (s. 9-10):
Privat synlighet är en konstruktion för designstid; den tillämpas under statisk typkontroll men innebär inte någon körningstidskontroll. ... TypeScript tillämpar inkapsling av implementeringar i klasser vid designstid (genom att begränsa användningen av privata medlemmar), men kan inte tillämpa inkapsling vid körningstid eftersom alla objektets egenskaper är åtkomliga vid körning. Framtida versioner av JavaScript kan tillhandahålla privata namn som skulle möjliggöra körningstidskontroll av privata medlemmar.
Detta har redan frågats och besvarats här: https://stackoverflow.com/a/12713869/1014822
Uppdatering: Detta gamla svar får fortfarande en del trafik, så det är värt att notera att, utöver länk till språkets specifikation ovan, behandlas publika, privata och (nu) skyddade medlemmar i detalj i TypeScript-handboken i kapitlet om klasser.
Uppdatering 2018 Implementering av ES Private Fields är nu en framtida punkt på TypeScript RoadMap, även om diskussionen tyder på att detta kommer att vara ett parallellt alternativ med hård privat, inte en ersättning för den nuvarande mjuka privata implementeringen.
Uppdatering 2020 Körtidsprivata fält som använder #-operatören har implementerats från och med TS 3.8. Det finns en bra diskussion om hur de fungerar och hur de skiljer sig från kompileringstidsfält med private-nyckelordet på StackOverflow här.
Privata metoder har nått steg 3 i TC39-arbetsgruppen. Funktionen diskuteras för närvarande aktivt för TypeScript, till exempel här.
Svar #2
I Javascript (till skillnad från TypeScript) kan du inte ha en privat "member"-funktion.
Om du definierar en privat funktion i closure, kommer du inte kunna anropa den som en instansmetod på en instans av din klass.
Om det är vad du vill, flytta bara TypeScript-funktionsdefinitionen utanför klasskroppen.