Private Eigenschaften in JavaScript ES6-Klassen
Ist es möglich, erstellen Sie private Eigenschaften in ES6-Klassen?
Hier ist ein Beispiel.
Wie kann ich verhindern, dass der Zugang zu instance.property
?
class Something {
constructor(){
this.property = "test";
}
}
var instance = new Something();
console.log(instance.property); //=> "test"
InformationsquelleAutor der Frage d13 | 2014-03-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kurze Antwort, Nein, es gibt keine native Unterstützung für private Immobilien mit ES6-Klassen.
Aber könnten Sie ahmen das Verhalten von nicht anbringen, die neue Eigenschaften zum Objekt, aber behalten Sie Sie in einen Konstruktor der Klasse, und verwenden Sie Getter und setter zu erreichen, die verborgenen Eigenschaften. Beachten Sie, dass die Getter und setter wird neu definieren, die auf jeder neuen Instanz der Klasse.
ES6
ES5
InformationsquelleAutor der Antwort MetalGodwin
Erweitern @loganfsmyth Antwort:
Nur eine wirklich private Daten in JavaScript-noch scoped Variablen. Sie können keine privaten Eigenschaften im Sinne von Eigenschaften zugegriffen intern die gleiche Weise wie öffentliche Eigenschaften, aber Sie können den Gültigkeitsbereich von Variablen zum speichern von privaten Daten.
Gültigkeitsbereich von Variablen
Der Ansatz ist hier, den Anwendungsbereich der Konstruktor-Funktion, die private, zum speichern von privaten Daten. Für Methoden zum Zugriff auf diese privaten Daten, die Sie erstellt werden muss innerhalb des Konstruktors als auch, also sind Sie diese anschließend mit jeder Instanz. Dies ist ein performance-und Speicher-Strafe, aber einige glauben, dass die Strafe akzeptabel ist. Die Strafe kann vermieden werden, für Methoden, die nicht brauchen, um Zugang zu den privaten Daten, indem Sie Sie der Prototyp als üblich.
Beispiel:
Gültigkeitsbereich WeakMap
Einen WeakMap kann verwendet werden, um zu vermeiden, den früheren Ansatz, die performance-und memory-Strafe. WeakMaps Daten zuordnen von Objekten (Instanzen) in einer solchen Weise, dass es kann nur zugegriffen werden, WeakMap. So verwenden wir den Gültigkeitsbereich von Variablen Methode zum erstellen einer privaten WeakMap, verwenden Sie dann WeakMap zum abrufen von privaten Daten, die im Zusammenhang mit
this
. Dieser ist schneller als der Gültigkeitsbereich von Variablen, Methode, weil alle Ihre Instanzen teilen sich die einzelnen WeakMap, so brauchen Sie nicht neu zu erstellen Methoden, nur um Ihnen den Zugriff auf Ihre eigenen WeakMaps.Beispiel:
In diesem Beispiel wird ein Objekt, das eine WeakMap für mehrere private Eigenschaften; Sie können auch mehrere WeakMaps und verwenden Sie wie
age.set(this, 20)
oder schreiben Sie eine kleine Schutzfolie, und verwenden Sie es auf andere Weise, wieprivateProps.set(this, 'age', 0)
.Die Privatsphäre dieser Ansatz könnte theoretisch auch verletzt werden, durch die Manipulation des globalen
WeakMap
Objekt. Das heißt, alle JavaScript werden kann, gebrochen durch die entstellten globals. Unser code ist bereits gebaut, auf der Annahme, dass dies nicht passiert.(Diese Methode könnte auch mit
Map
, aberWeakMap
ist besser, weilMap
erstellen memory leaks, es sei denn, Sie sind sehr vorsichtig, und zu diesem Zweck die zwei sind ansonsten nicht anders.)Halbe Antwort: Der Gültigkeitsbereich Von Symbolen
Symbol ist eine Art von primitiven Wert, die dienen kann, als den Namen der Eigenschaft. Sie können den Gültigkeitsbereich von Variablen Methode, um ein eigenes Symbol, und dann auf speichern privater Daten auf
this[mySymbol]
.Die Privatsphäre dieser Methode kann durchbrochen werden mit
Object.getOwnPropertySymbols
, ist aber etwas umständlich zu tun.Beispiel:
Hälfte-Antwort: Unterstrichen
Den alten Standard, nur Sie eine öffentliche Eigenschaft mit einem Unterstrich-prefix. Obwohl nicht ein privates Eigentum in keiner Weise, diese Konvention ist weit verbreitet genug, dass es macht einen guten job der Kommunikation, die Leser sollten behandeln Sie die Eigenschaft als private, die oft bekommt den job getan. Im Austausch für diese verfallen, bekommen wir einen Ansatz, der einfacher zu Lesen, einfacher zu Tippen, und schneller.
Beispiel:
Abschluss
Als der ES2017, es gibt immer noch keine perfekte Weg, dies zu tun private Eigenschaften. Verschiedene Ansätze haben vor-und Nachteile. Gültigkeitsbereich von Variablen sind wirklich private; Gültigkeitsbereich WeakMaps sind sehr privat und praktischer als Gültigkeitsbereich von Variablen; Gültigkeitsbereich Symbole sind angemessen private und praktisch; unterstreicht, sind oft privat genug und sehr praktisch.
InformationsquelleAutor der Antwort Tristan Berger
Update: Ein Vorschlag mit schöneren syntax ist auf dem Weg. Beiträge willkommen.
Ja, es ist - für scoped access-Objekte - ES6 stellt
Symbol
s.Symbole sind einzigartig, Sie können nicht Zugriff auf eine von außen nur mit Reflexion (wie Soldaten in Java/C#), aber jeder, der Zugriff auf ein symbol auf der Innenseite können Sie für Schlüssel Zugang:
InformationsquelleAutor der Antwort Benjamin Gruenbaum
Die Antwort ist "Nein". Aber Sie können erstellen Sie einen privaten Zugang zu Eigenschaften wie dieses:
export
Stichwort.(Der Vorschlag, dass Symbole verwendet werden könnte, um Privatsphäre zu gewährleisten, war wahr, die in einer früheren version des ES6 spec, ist aber nicht mehr der Fall:https://mail.mozilla.org/pipermail/es-discuss/2014-January/035604.html und https://stackoverflow.com/a/22280202/1282216. Für eine längere Diskussion über Symbole und Datenschutz finden Sie unter: https://curiosity-driven.org/private-properties-in-javascript)
InformationsquelleAutor der Antwort d13
Der einzige Weg, um echte Privatsphäre in JS wird durch das scoping, also es gibt keine Möglichkeit, eine Eigenschaft, die ein Mitglied der
this
zugänglich werden, die nur innerhalb der Komponente. Der beste Weg, um wirklich private Daten in ES6 ist mit einem WeakMap.Offensichtlich ist dies eine wohl nur langsam, und definitiv hässlich, aber es funktioniert Privatsphäre zu bieten.
Beachten Sie, dass AUCH DIESER ist nicht perfekt, denn Javascript ist so dynamisch. Könnte jemand noch tun
fangen Werte, wie Sie gespeichert werden, so dass, wenn Sie wollte besonders vorsichtig sein, würden Sie brauchen, um zu erfassen eine lokale Referenz auf
.set
und.get
zu verwenden, die explizit anstatt sich auf die überschreibbare Prototyp.InformationsquelleAutor der Antwort loganfsmyth
Referenz für die Zukunft auf der anderen Zuschauern, ich höre jetzt, dass die Empfehlung ist, WeakMaps zu halten privaten Daten.
Hier ist eine klare, arbeiten Beispiel:
InformationsquelleAutor der Antwort
Hängt davon ab,wen Sie Fragen : -)
Kein
private
Eigenschaft modifier enthalten ist in der Maximal minimal Klassen Vorschlag, die scheint, haben es in der aktuellen Entwurf.Allerdings könnte es sein,Unterstützung für private-Namen, die zulässt, dass private Eigenschaften - und Sie wahrscheinlich verwendet werden könnten, in der Klasse-Definitionen als auch.
InformationsquelleAutor der Antwort Bergi
Abschluss @d13 und die Kommentare von @johnny-oshika und @DanyalAytekin:
Ich denke, dass in dem Beispiel von @johnny-oshika können wir die normalen Funktionen anstelle der Pfeil-Funktionen und dann
.bind
Sie mit dem aktuellen Objekt plus ein_privates
Objekt als Curry-parameter:something.js
main.js
Vorteile, die ich denken kann:
_greet
und_updateMessage
handeln wie private Methoden, solange wir nichtexport
Referenzen)_privates
ObjektEinige Nachteile, die ich mir denken kann:
Einer Laufenden snippet kann hier gefunden werden: http://www.webpackbin.com/NJgI5J8lZ
InformationsquelleAutor der Antwort efidiles
Verwendung von ES6-Modulen (ursprünglich vorgeschlagen von @d13) funktioniert gut für mich. Ist es nicht nachzuahmen private Eigenschaften perfekt, aber mindestens Sie können sicher sein, dass Eigenschaften, die privat nicht Leck außerhalb der Klasse. Hier ist ein Beispiel:
something.js
Dann die Konsum-code kann wie folgt Aussehen:
Update (Wichtig):
Als @DanyalAytekin beschrieben in die Kommentare, diese private Eigenschaften sind statisch, also global angelegt. Sie funktionieren gut, wenn die Arbeit mit Singletons, aber Sorgfalt getroffen werden müssen, für Transiente Objekte. Erweitern das obige Beispiel:
InformationsquelleAutor der Antwort Johnny Oshika
Ja - Sie erstellen gekapselt Eigenschaft, aber es ist nicht getan mit zugriffsmodifizierer (public|private) zumindest nicht mit ES6.
Hier ist ein einfaches Beispiel, wie es getan werden kann, mit ES6:
1 Erstellen Sie eine Klasse mit Klasse Wort
2 Innen-Konstruktor deklarieren, block-Gültigkeitsbereich von Variablen mit lassen ODER const reservierte Wörter -> da sind Sie block-Geltungsbereich, Sie kann nicht von außen zugreifbar sein (gekapselt)
3 Zu ermöglichen, dass einige access control (setter|Getter) auf diese Variablen können Sie angeben, Instanz-Methode ist es innen Konstruktor verwenden:
this.methodName=function(){}
syntaxNun lässt es überprüfen:
InformationsquelleAutor der Antwort Nikita Kurtin
WeakMap
Object.getOwnPropertySymbols
)Zuerst eine Funktion definieren, zu wickeln WeakMap:
Dann konstruieren Sie eine Referenz außerhalb Ihrer Klasse:
Hinweis: Klasse nicht unterstützt IE11, aber es sieht sauberer aus, im Beispiel.
InformationsquelleAutor der Antwort kevlened
Einen anderen Ansatz, um die "privaten"
Statt des Kampfes gegen die Tatsache, dass die Sichtbarkeit "private" ist derzeit nicht verfügbar in ES6, entschied ich mich für einen mehr praktischen Ansatz, der einfach gut tut, wenn Ihre IDE unterstützt JSDoc (z.B. Webstorm). Die Idee ist, die
@private
- tag. Wie weit die Entwicklung geht, wird die IDE verhindern, dass Sie Zugriff auf private member von außerhalb seiner Klasse. Funktioniert ziemlich gut für mich und es war wirklich nützlich für das verstecken von internen Methoden, damit die auto-vervollständigen-Funktion zeigt mir nur das, was die Klasse wirklich bedeutet, zu entlarven. Hier ist ein Beispiel:InformationsquelleAutor der Antwort Lucio Paiva
Gefällt mir persönlich der Vorschlag der bind-operator
::
und würde dann kombinieren Sie es mit der Lösung @d13 erwähnt, aber für jetzt-stick mit @d13 's Antwort, wo Sie mit denexport
Schlüsselwort für Ihre Klasse und setzen die privaten Funktionen in das Modul.gibt es eine weitere Lösung hart, die noch nicht erwähnt wurden, die folgt, sind eher funktionalen Ansatz und der ihm erlauben würde, um alle privaten Requisiten/Methoden innerhalb der Klasse.
Private.js
Test.js
Kommentare es würde geschätzt werden.
InformationsquelleAutor der Antwort Robin F.
Ich denke Benjamins Antwort ist wahrscheinlich das beste für den meisten Fällen, bis die Sprache nativ unterstützt ausdrücklich die privaten Variablen.
Jedoch, wenn aus irgendeinem Grund müssen Sie verhindern, dass der Zugang mit
- Objekt.getOwnPropertySymbols()
, eine Methode, die ich betrachtet habe verwenden, ist das anbringen einer einmaligen, nicht konfigurierbar, nicht-aufzählbare, nicht beschreibbare Eigenschaft, die verwendet werden kann als eine Eigenschaft Bezeichner für jedes Objekt auf dem Bau (wie eine einzigartigeSymbol
, wenn Sie nicht bereits haben einige andere einzigartige Eigenschaft, wie einid
). Dann einfach immer eine Karte von jedem Objekt eine "private" Variable, die Bezeichner.Den möglichen Vorteil dieser Vorgehensweise gegenüber der Verwendung einer
WeakMap
ist Zeit für schnelleren Zugriff wenn Leistung wichtig ist, ein Anliegen.InformationsquelleAutor der Antwort NanoWizard
InformationsquelleAutor der Antwort Ilya Zarembsky
Sogar Typoskript kann es nicht tun. Von Ihren Dokumentation:
Aber transpiled auf Ihre Spielplatz gibt es:
Damit Ihre "private" Stichwort ist unwirksam.
InformationsquelleAutor der Antwort Michael Franzl
Kommen sehr spät zu dieser party, aber ich traf die OP-Frage in eine Suche so...
Ja, Sie können private Eigenschaften, indem er die Deklaration der Klasse in einer Schließung
Es ist ein Beispiel, wie man private Methoden in in diesem codepen. In dem snippet unten, die Abonnierbare Klasse hat zwei "privaten" Funktionen
process
undprocessCallbacks
. Alle Eigenschaften können auf diese Weise Hinzugefügt, und Sie werden privat gehalten, die durch die Nutzung der Schließung. IMO Privatsphäre ist ein Seltenes müssen, wenn Bedenken sind gut getrennt und Javascript nicht braucht, zu aufgebläht, indem Sie weitere syntax, wenn ein Verschluss ordentlich macht den job.Ich mag diesen Ansatz, da er trennt Bedenken schön und hält die Dinge wirklich privat. Der einzige Nachteil ist die Notwendigkeit für die Verwendung von 'selbst' (oder so ähnlich) zu Lesen 'dieser' in der privaten Inhalte.
InformationsquelleAutor der Antwort Paul Whipp
Sehen diese Antwort für eine clean & simple 'class' - Lösung mit einem privaten und öffentlichen Schnittstelle und Unterstützung für Komposition
InformationsquelleAutor der Antwort kofifus
Fand ich eine sehr einfache Lösung, nur mit
Object.freeze()
. Natürlich ist das problem ist Sie können nicht hinzufügen nichts, um das Objekt später.InformationsquelleAutor der Antwort Nikola Andreev
Eigentlich ist es ist möglich.
InformationsquelleAutor der Antwort Paweł
Andere Art und Weise ähnlich zu den letzten zwei gepostet
InformationsquelleAutor der Antwort Jayesbe
Stieß ich auf diesen Beitrag bei der Suche nach der besten Praxis für die "privaten Daten-Klassen". Es wurde erwähnt, dass ein paar der Muster würde von performance-Problemen.
Ich zusammen ein paar jsperf-tests basiert auf den 4 wichtigsten Muster aus dem online-Buch "Exploring ES6":
http://exploringjs.com/es6/ch_classes.html#sec_private-data-for-classes
Des tests finden Sie hier:
https://jsperf.com/private-data-for-classes
In Chrom 63.0.3239 /Mac OS X 10.11.6 die beste Leistung Muster waren "Private Daten über Konstruktor-Umgebungen" und "Private Daten über eine Namenskonvention". Für mich Safari durchgeführt, die auch für WeakMap aber Chrome nicht so gut.
Ich weiß nicht, der Arbeitsspeicher, aber das Muster für die "Konstruktor-Umgebungen", die einige gewarnt hatten, wäre ein performance-Problem wurde sehr performant.
Die 4 grundlegenden Muster sind:
Private Daten über Konstruktor-Umgebungen
Private Daten über Konstruktor-Umgebungen 2
Private Daten über eine Namenskonvention
Private Daten über WeakMaps
Private Daten über Symbole
InformationsquelleAutor der Antwort MarkM
Hier, die myThing variable ist privat und ist Teil von der Schließung:
InformationsquelleAutor der Antwort Naga Chaitanya Konada