Um eine JavaScript-Klasse mit einer öffentlichen Methode zu erstellen, würde ich Folgendes tun:
function Restaurant() {}
Restaurant.prototype.buy_food = function(){
// something here
}
Restaurant.prototype.use_restroom = function(){
// something here
}
Auf diese Weise können Benutzer meiner Klasse:
var restaurant = new Restaurant();
restaurant.buy_food();
restaurant.use_restroom();
Wie erstelle ich eine private Methode, die von den Methoden buy_food
und aufgerufen werden use_restroom
kann, jedoch nicht extern von Benutzern der Klasse?
Mit anderen Worten, ich möchte, dass meine Methodenimplementierung Folgendes kann:
Restaurant.prototype.use_restroom = function() {
this.private_stuff();
}
Das sollte aber nicht funktionieren:
var r = new Restaurant();
r.private_stuff();
Wie definiere ich private_stuff
eine private Methode, damit beide zutreffen?
Ich habe Doug Crockfords Artikel einige Male gelesen, aber es scheint nicht, dass "private" Methoden von öffentlichen Methoden aufgerufen werden können und "privilegierte" Methoden extern aufgerufen werden können.
quelle
Verwenden der selbstaufrufenden Funktion und des Aufrufs
JavaScript verwendet Prototypen und verfügt nicht über Klassen (oder Methoden) wie objektorientierte Sprachen. Ein JavaScript-Entwickler muss in JavaScript denken.
Wikipedia-Zitat:
Lösung mit einer selbstaufrufenden Funktion und der Aufruffunktion zum Aufrufen der privaten "Methode":
Mit der Aufruffunktion können wir die private Funktion mit dem entsprechenden Kontext aufrufen (
this
).Einfacher mit Node.js.
Wenn Sie node.js verwenden , benötigen Sie das IIFE nicht, da Sie das Modulladesystem nutzen können :
Laden Sie die Datei:
(experimentell) ES7 mit dem Bind Operator
Der Bindungsoperator
::
ist ein ECMAScript- Vorschlag und wird in Babel implementiert ( Stufe 0 ).Laden Sie die Datei:
quelle
.call
Teils.f()
in Javascript (im Moment nicht)..call
) und kleinen Speicher (keine Funktionen auf der Instanz) zu haben? Existiert das überhaupt?Sie können private Methoden wie folgt simulieren:
Weitere Informationen zu dieser Technik finden Sie hier: http://webreflection.blogspot.com/2008/04/natural-javascript-private-methods.html
quelle
In diesen Situationen, in denen Sie eine öffentliche API haben und private und öffentliche Methoden / Eigenschaften wünschen, verwende ich immer das Modulmuster. Dieses Muster wurde in der YUI-Bibliothek populär gemacht. Die Details finden Sie hier:
http://yuiblog.com/blog/2007/06/12/module-pattern/
Es ist wirklich einfach und für andere Entwickler leicht zu verstehen. Ein einfaches Beispiel:
quelle
aPrivateMethod = function() { MYLIB.aPublicProperty}
?Hier ist die Klasse, die ich erstellt habe, um zu verstehen, was Douglas Crockford auf seiner Website Private Members in JavaScript vorgeschlagen hat
quelle
that
wird verwendetthis
, um Scoping-Probleme zu vermeiden, wenn Funktionen an ein anderes Objekt gebunden sind. Hier werden Sie die Speicherungthis
inthat
und nie wieder mit denen ist das gleiche wie es überhaupt nicht tun. Sie solltenthis
mitthat
allenConstructor
inneren Funktionen wechseln (keine Methodendeklaration). Wennemployee
sichapply
ed odercall
in irgendeiner Weise ed werfen diese Methoden könnten dathis
wird falsch gebunden.Ich habe das heraufbeschworen: EDIT: Eigentlich hat sich jemand mit einer identischen Lösung verbunden. Duh!
quelle
var getAwayVehicle = new Car(100);
wo100
ist Geschwindigkeit und Sie möchten Geschwindigkeit alarmieren. Vielen Dank!var Car = function(speed) { this.speed = speed; }
und zurückgeben {Konstruktor: Auto, ... `Ich denke, solche Fragen tauchen immer wieder auf, weil die Schließungen nicht verstanden wurden. Verschlüsse sind das Wichtigste in JS. Jeder JS-Programmierer muss die Essenz davon spüren.
1. Zunächst müssen wir einen separaten Geltungsbereich festlegen (Abschluss).
2. In diesem Bereich können wir tun, was wir wollen. Und niemand wird davon erfahren.
3. Damit die Welt etwas über unsere Restaurantklasse weiß, müssen wir sie von der Schließung zurückgeben.
4. Am Ende haben wir:
5. Dieser Ansatz bietet auch Potenzial für Vererbung und Vorlagen
Ich hoffe, das hilft jemandem, dieses Thema besser zu verstehen
quelle
Persönlich bevorzuge ich das folgende Muster zum Erstellen von Klassen in JavaScript:
Wie Sie sehen, können Sie sowohl Klasseneigenschaften als auch Instanzeigenschaften definieren, von denen jede öffentlich und privat sein kann.
Demo
Siehe auch diese Geige .
quelle
All diese Schließung kostet Sie. Stellen Sie sicher, dass Sie die Auswirkungen auf die Geschwindigkeit insbesondere im Internet Explorer testen. Sie werden feststellen, dass Sie mit einer Namenskonvention besser dran sind. Es gibt immer noch viele Webbenutzer in Unternehmen, die gezwungen sind, IE6 zu verwenden ...
quelle
Sei nicht so wortreich. Es ist Javascript. Verwenden Sie eine Namenskonvention .
Nachdem ich jahrelang in es6-Klassen gearbeitet habe, habe ich kürzlich begonnen, an einem es5-Projekt zu arbeiten (mit requireJS, das bereits sehr ausführlich aussieht). Ich habe alle hier genannten Strategien immer wieder wiederholt und alles läuft im Grunde darauf hinaus, eine Namenskonvention zu verwenden :
private
. Andere Entwickler, die Javascript eingeben, wissen dies im Voraus. Daher ist eine einfache Namenskonvention mehr als ausreichend. Eine einfache Namenskonvention zum Präfixieren eines Unterstrichs löst das Problem sowohl privater Eigenschaften als auch privater Methoden.my-tooltip.js
quelle
define
undconstructor
und die Struktur selbst. Obwohl ich der Antwort größtenteils zustimme, habe ich angefangen, mit JS mit viel OOP-Einfluss zu arbeiten, und bin sogar zu früh zu TS gesprungen, da ich zuvor Erfahrung mit C # hatte. Ich denke, ich muss diese Dinge verlernen und das Prototyping- / Verfahrensparadigma verstehen. (upvoted, übrigens)Sie können dies jetzt mit privaten es10-Methoden tun . Sie müssen nur ein
#
vor dem Methodennamen einfügen.quelle
Nehmen Sie eine der Lösungen, die Crockfords privatem oder privilegiertem Muster folgen . Zum Beispiel:
In jedem Fall, in dem der Angreifer kein "Ausführungsrecht" im JS-Kontext hat, hat er keine Möglichkeit, auf "öffentliche" oder "private" Felder oder Methoden zuzugreifen. Falls der Angreifer diesen Zugriff hat, kann er diesen Einzeiler ausführen:
Beachten Sie, dass der obige Code für alle Konstruktortyp-Datenschutzdaten generisch ist. Bei einigen der hier aufgeführten Lösungen wird dies fehlschlagen, aber es sollte klar sein, dass so gut wie alle auf Verschlüssen basierenden Lösungen auf unterschiedliche Weise auf diese Weise beschädigt werden können
replace()
Parametern auf beschädigt werden können.Nachdem dies ausgeführt wurde, verfügt jedes mit erstellte Objekt
new Foo()
über eineeval
Methode, die aufgerufen werden kann, um Werte oder Methoden zurückzugeben oder zu ändern, die im Abschluss des Konstruktors definiert sind, z.Das einzige Problem, das ich dabei sehen kann, ist, dass es in Fällen, in denen es nur eine Instanz gibt und die beim Laden erstellt wird, nicht funktioniert. Es gibt jedoch keinen Grund, einen Prototyp tatsächlich zu definieren. In diesem Fall kann der Angreifer das Objekt anstelle des Konstruktors einfach neu erstellen, solange er die Möglichkeit hat, dieselben Parameter zu übergeben (z. B. sind sie konstant oder werden aus verfügbaren Werten berechnet).
Meiner Meinung nach macht dies Crockfords Lösung ziemlich nutzlos.Da die "Privatsphäre" leicht verletzt werden kann, sind die Nachteile seiner Lösung (verminderte Lesbarkeit und Wartbarkeit, verminderte Leistung, mehr Speicher) die prototypbasierte Methode "keine Privatsphäre" die bessere Wahl.
Normalerweise verwende ich führende Unterstriche zum Markieren
__private
und für_protected
Methoden und Felder (Perl-Stil), aber die Idee, Datenschutz in JavaScript zu haben, zeigt nur, dass es sich um eine missverstandene Sprache handelt.Daher bin ich mit Crockford bis auf seinen ersten Satz nicht einverstanden .
Wie erhalten Sie echte Privatsphäre in JS? Stellen Sie alles, was erforderlich ist, um privat zu sein, auf die Serverseite und verwenden Sie JS, um AJAX-Aufrufe auszuführen.
quelle
(function () {allMyStuff}());
, um nichts Globales preiszugeben.f.eval('nameOfVariable')
wenn Sie nicht wissen, was'nameOfVariable'
ist ...Die Apotheose des Modulmusters: Das aufschlussreiche Modulmuster
Eine nette kleine Erweiterung zu einem sehr robusten Muster.
quelle
Wenn Sie alle öffentlichen und privaten Funktionen mit der Möglichkeit für öffentliche Funktionen nutzen möchten, auf private Funktionen zuzugreifen, geben Sie den Layoutcode für ein Objekt wie das folgende ein:
quelle
new MyObject
, wird der Prototyp vonMyObject
durch dieselben Werte ersetzt..prototype
dem Konstruktor niemals das Innere zu.Ähnlich wie Georgebrock, aber etwas weniger ausführlich (IMHO) Haben Sie Probleme damit? (Ich habe es nirgendwo gesehen)
edit: Mir wurde klar, dass dies irgendwie nutzlos ist, da jede unabhängige Instanziierung eine eigene Kopie der öffentlichen Methoden hat, was die Verwendung des Prototyps untergräbt.
quelle
Folgendes hat mir bisher am besten gefallen in Bezug auf private / öffentliche Methoden / Mitglieder und Instanziierung in Javascript:
Hier ist der Artikel: http://www.sefol.com/?p=1090
und hier ist das Beispiel:
JSFiddle: http://jsfiddle.net/northkildonan/kopj3dt3/1/
quelle
Das Modulmuster ist in den meisten Fällen richtig. Wenn Sie jedoch Tausende von Instanzen haben, sparen Klassen Speicher. Wenn das Speichern von Speicher ein Problem darstellt und Ihre Objekte eine kleine Menge privater Daten enthalten, aber viele öffentliche Funktionen haben, möchten Sie, dass alle öffentlichen Funktionen im Prototyp gespeichert werden, um Speicher zu sparen.
Das habe ich mir ausgedacht:
Das Objekt
priv
enthält private Eigenschaften. Der Zugriff ist über die öffentliche Funktion möglichgetPriv()
. Diese Funktion wird jedoch zurückgegeben,false
sofern Sie sie nicht übergeben.secret
Dies ist nur innerhalb des Hauptabschlusses bekannt.quelle
Was ist damit?
Die Suche nach privaten Variablen ist außerhalb des Bereichs der unmittelbaren Funktion nicht möglich. Es gibt keine doppelten Funktionen, wodurch Speicherplatz gespart wird.
Der Nachteil ist, dass die Suche nach privaten Variablen klobig
privateVars[this.id].cooked
ist und lächerlich zu tippen ist. Es gibt auch eine zusätzliche "id" -Variable.quelle
Restaurant
als würdenundefined
Sie nichts von der anonymen Funktion zurückgeben.Restaurant
Müll gesammelt wurde, bleiben ihre Werte innerhalbprivateVars
. AWeakMap
kannArray
in diesem Fall ein guter Ersatz für das sein .Wickeln Sie den gesamten Code in die anonyme Funktion: Dann sind alle Funktionen privat und NUR mit Funktionen verbunden
window
Objekt :Benutze das :
GEIGE
quelle
Ich bevorzuge es, private Daten in einem zugehörigen zu speichern
WeakMap
. Auf diese Weise können Sie Ihre öffentlichen Methoden auf dem Prototyp belassen, zu dem sie gehören. Dies scheint der effizienteste Weg zu sein, um dieses Problem für eine große Anzahl von Objekten zu lösen.quelle
Private Funktionen können nicht über das Modulmuster auf die öffentlichen Variablen zugreifen
quelle
Da jeder hier seinen eigenen Code gepostet hat, werde ich das auch tun ...
Ich mag Crockford, weil er echte objektorientierte Muster in Javascript eingeführt hat. Aber er hatte auch ein neues Missverständnis, das "das".
Warum benutzt er "das = das"? Es hat überhaupt nichts mit privaten Funktionen zu tun. Es hat mit inneren Funktionen zu tun!
Denn laut Crockford ist dies ein fehlerhafter Code:
Also schlug er Folgendes vor:
Wie gesagt, ich bin mir ziemlich sicher, dass Crockford seine Erklärung zu diesem und jenem falsch war (aber sein Code ist sicherlich korrekt). Oder hat er nur die Javascript-Welt zum Narren gehalten, um zu wissen, wer seinen Code kopiert? Ich weiß nicht ... Ich bin kein Browser-Geek; D.
BEARBEITEN
Ah, darum geht es: Was bedeutet 'var that = this'? meine in JavaScript?
Also war Crockie wirklich falsch mit seiner Erklärung ... aber richtig mit seinem Code, also ist er immer noch ein großartiger Kerl. :))
quelle
Im Allgemeinen habe ich das private Objekt _ vorübergehend zum Objekt hinzugefügt. Sie müssen den Datenschutz exklusiv im "Power-Konstruktor" für die Methode öffnen. Wenn Sie die Methode vom Prototyp aus aufrufen, können Sie die Prototypmethode überschreiben
Machen Sie eine öffentliche Methode im "Power-Konstruktor" zugänglich: (ctx ist der Objektkontext)
Jetzt habe ich diese openPrivacy:
quelle
Das habe ich herausgefunden:
Benötigt eine Klasse von Zuckercode, die Sie hier finden können . Unterstützt auch geschützte, vererbbare, virtuelle, statische ...
quelle
https://github.com/nooning/JSClass
quelle
Ich habe ein neues Tool erstellt, mit dem Sie echte private Methoden für den Prototyp https://github.com/TremayneChrist/ProtectJS verwenden können
Beispiel:
quelle
_private
Methode aufrufen ?Sie müssen Ihre eigentliche Konstruktorfunktion schließen, um Ihre privaten Methoden zu definieren. Um Daten der Instanzen durch diese privaten Methoden zu ändern, müssen Sie ihnen "dies" geben, entweder als Funktionsargument oder indem Sie diese Funktion mit .apply (this) aufrufen:
quelle
new Restaurant
wird seinen eigenenrestaurant
Konstruktor haben, und der "Prototyp" wird total missbraucht.Ich weiß, dass es etwas zu spät ist, aber wie wäre es damit?
quelle
Es gibt bereits viele Antworten auf diese Frage, aber nichts entsprach meinen Bedürfnissen. Also habe ich meine eigene Lösung gefunden, ich hoffe, sie ist für jemanden nützlich:
Wie Sie sehen können, funktioniert dieses System, wenn diese Art von Klassen in Javascript verwendet wird. Soweit ich herausgefunden habe, hat keine der oben kommentierten Methoden dies getan.
quelle
In dieser Antwort finden Sie eine saubere und einfache "Klassen" -Lösung mit einer privaten und öffentlichen Schnittstelle und Unterstützung für die Komposition
quelle