Was ist der einfachste / sauberste Weg, um Singleton-Muster in JavaScript zu implementieren?
javascript
function
design-patterns
singleton
Jakub Arnold
quelle
quelle
Antworten:
Ich denke, der einfachste Weg ist, ein einfaches Objektliteral zu deklarieren:
Wenn Sie private Mitglieder in Ihrer Singleton-Instanz haben möchten, können Sie Folgendes tun:
Dies wurde genannt das Modul Muster , es im Grunde können Sie private Mitglieder auf ein Objekt kapseln, von Vorteil bei der Verwendung der Einnahme Schließungen .
UPDATE: Ich möchte hinzufügen, dass Sie das Singleton-Objekt mithilfe der ES5- Methode einfrieren können, wenn Sie die Änderung des Singleton-Objekts verhindern möchten
Object.freeze
.Dadurch wird das Objekt unveränderlich und es werden keine Änderungen an seiner Struktur und seinen Werten vorgenommen.
Darüber hinaus möchte ich erwähnen, dass Sie mit ES6 sehr einfach einen Singleton mit ES-Modulen darstellen und sogar den privaten Status beibehalten können, indem Sie Variablen im Modulbereich deklarieren :
Dann können Sie einfach das Singleton-Objekt importieren, um es zu verwenden:
quelle
publicMethod1
anrufenpublicMethod2
?getInstance
Methode und einen privaten Konstruktor beinhalteten -, aber IMO, dies ist der "einfachste" Weg, ein Singleton-Objekt zu erstellen in Javascript, und am Ende erfüllt es den gleichen Zweck - ein einzelnes Objekt, das Sie nicht erneut initialisieren können (es gibt keinen Konstruktor, es ist nur ein Objekt) -. Über den Code, den Sie verlinkt haben, gibt es einige Probleme, tauschen Sie diea
undb
Variablendeklarationen aus und testen Siea === window
. Prost.Ich denke, der sauberste Ansatz ist so etwas wie:
Anschließend können Sie die Funktion als aufrufen
quelle
delete instance.constructor
:x = SingletonClass.getInstance();delete x.constructor;new x.constructor;
Ich bin nicht sicher, ob ich mit dem Modulmuster einverstanden bin, das als Ersatz für ein Singleton-Muster verwendet wird. Ich habe oft gesehen, wie Singletons an Orten verwendet und missbraucht wurden, an denen sie völlig unnötig sind, und ich bin sicher, dass das Modulmuster viele Lücken füllt, in denen Programmierer sonst einen Singleton verwenden würden, aber das Modulmuster ist kein Singleton.
Modulmuster:
Alles, was im Modulmuster initialisiert wurde, geschieht, wenn
Foo
es deklariert wird. Zusätzlich kann das Modulmuster verwendet werden, um einen Konstruktor zu initialisieren, der dann mehrmals instanziiert werden kann. Während das Modulmuster das richtige Werkzeug für viele Jobs ist, entspricht es nicht einem Singleton.Singleton-Muster:
Kurzform lange Form mit ModulmusterIn beiden Versionen des von mir bereitgestellten Singleton-Musters kann der Konstruktor selbst als Accessor verwendet werden:
Wenn Sie sich mit dem Konstruktor auf diese Weise nicht wohl fühlen, können Sie einen Fehler in die
if (instance)
Anweisung werfen und sich an die lange Form halten:Ich sollte auch erwähnen, dass das Singleton-Muster gut zum impliziten Konstruktorfunktionsmuster passt:
quelle
var singleton = {}
passt nicht zu dieser Definition.var singleton = {}
So implementieren Sie Singleton in Javascript .In
es6
:quelle
instance
Feld haben würde. Da es derzeit (instance
aufthis
) gesetzt ist, kann diese Klasse auch andere Felder haben und das Einfrieren macht imo keinen Sinn.Das Folgende funktioniert in Knoten v6
Wir testen:
quelle
In ES6 ist der richtige Weg, dies zu tun:
Wenn Sie nicht möchten, dass bei der Erstellung der zweiten Instanz ein Fehler ausgegeben wird, können Sie einfach die letzte Instanz wie folgt zurückgeben:
quelle
instance
und_instance
. Es ist nur eine Namenskonvention in Programmiersprachen, dass wir private Variablen benennen, denen ein Unterstrich vorangestellt ist. Ich vermute, der Grund dafür, dass Ihr Code nicht funktioniert, ist, dass Siethis.instance
anstelle vonMyClass.instance
Es gibt mehrere Möglichkeiten, eine Katze zu häuten :) Je nach Geschmack oder Bedarf können Sie eine der vorgeschlagenen Lösungen anwenden. Ich persönlich greife nach Möglichkeit zur ersten Lösung von CMS (wenn Sie keine Privatsphäre benötigen). Da es sich um die einfachste und sauberste Frage handelte, ist dies der Gewinner. Oder auch:
Dies (Zitat aus meinem Blog) ...
macht nicht viel Sinn (mein Blog-Beispiel auch nicht), weil es keine privaten Vars benötigt, also ist es so ziemlich das Gleiche wie:
quelle
this.f(){}
Ich lehne meine Antwort ab, siehe meine andere .
Normalerweise ist ein Modulmuster (siehe Antwort von CMS), das KEIN Singleton-Muster ist, gut genug. Eines der Merkmale von Singleton ist jedoch, dass seine Initialisierung verzögert wird, bis ein Objekt benötigt wird. Dem Modulmuster fehlt diese Funktion.
Mein Vorschlag (CoffeeScript):
Welche dazu in JavaScript kompiliert:
Dann kann ich folgendes tun:
quelle
Kurze Antwort:
Da JavaScript nicht blockierend ist, werden Singletons in JavaScript sehr hässlich verwendet. Globale Variablen geben Ihnen auch eine Instanz durch die gesamte Anwendung ohne all diese Rückrufe. Das Modulmuster verbirgt die Interna sanft hinter der Schnittstelle. Siehe @ CMS-Antwort.
Aber da Sie einen Singleton wollten ...
Verwendungszweck:
Erläuterung:
Singletons bieten Ihnen mehr als nur eine Instanz für die gesamte Anwendung: Ihre Initialisierung wird bis zur ersten Verwendung verzögert. Dies ist eine wirklich große Sache, wenn Sie sich mit Objekten befassen, deren Initialisierung teuer ist. Teuer bedeutet normalerweise E / A und in JavaScript bedeutet E / A immer Rückrufe.
Vertraue keinen Antworten, die dir eine Schnittstelle geben
instance = singleton.getInstance()
, sie verfehlen alle den Punkt.Wenn sie keinen Rückruf annehmen, um ausgeführt zu werden, wenn die Instanz bereit ist, funktionieren sie nicht, wenn der Initialisierer E / A ausführt.
Ja, Rückrufe sehen immer hässlicher aus als Funktionsaufrufe, die sofort eine Objektinstanz zurückgeben. Aber noch einmal: Wenn Sie E / A ausführen, sind Rückrufe obligatorisch. Wenn Sie keine E / A ausführen möchten, ist die Instanziierung billig genug, um sie beim Programmstart auszuführen.
Beispiel 1, billiger Initialisierer:
Beispiel 2, Initialisierung mit E / A:
In diesem Beispiel wird
setTimeout
eine teure E / A-Operation vorgetäuscht. Dies zeigt, warum Singletons in JavaScript wirklich Rückrufe benötigen.quelle
Ich habe dieses Beispiel von JavaScript-Mustern erhalten. Bessere Anwendungen mit Codierungs- und Entwurfsmustern erstellen Von Stoyan Stefanovs Buch Für den Fall, dass Sie eine einfache Implementierungsklasse wie ein Singltone-Objekt benötigen, können Sie die sofortige Funktion wie folgt verwenden:
Sie können dieses Beispiel anhand des folgenden Testfalls überprüfen:
Dieser Ansatz besteht alle Testfälle, während die private statische Implementierung fehlschlägt, wenn die Prototyperweiterung verwendet wird (sie kann behoben werden, ist aber nicht einfach) und die öffentliche statische Implementierung weniger ratsam ist, da die Instanz der Öffentlichkeit zugänglich ist.
jsFiddly Demo.
quelle
Ich glaube, ich habe den saubersten Weg gefunden, um in JavaScript zu programmieren, aber Sie brauchen etwas Fantasie. Ich habe diese Idee von einer Arbeitstechnik im Buch "Javascript the good parts" erhalten.
Anstatt das neue Schlüsselwort zu verwenden, können Sie eine Klasse wie die folgende erstellen:
Sie können das obige Objekt instanziieren, indem Sie sagen:
Mit dieser Arbeitsmethode können Sie nun einen Singleton wie folgt erstellen:
Jetzt können Sie Ihre Instanz durch Aufrufen erhalten
Ich denke, dies ist der sauberste Weg, da die gesamte "Klasse" nicht einmal zugänglich ist.
quelle
@CMS und @zzzzBov haben beide wundervolle Antworten gegeben, aber nur um meine eigene Interpretation hinzuzufügen, basierend darauf, dass ich in die Entwicklung von Heavy Node.js aus PHP / Zend Framework gewechselt bin, wo Singleton-Muster üblich waren.
Der folgende, kommentarisch dokumentierte Code basiert auf den folgenden Anforderungen:
Mein Code ist dem von @ zzzzBov sehr ähnlich, außer dass ich dem Konstruktor eine Prototypenkette und weitere Kommentare hinzugefügt habe, die denjenigen helfen sollen, die aus PHP oder einer ähnlichen Sprache stammen, die traditionelle OOP in die prototypische Natur von Javascripts zu übersetzen. Es ist vielleicht nicht das "einfachste", aber ich glaube, es ist das richtigste.
Beachten Sie, dass die selbstausführende anonyme Funktion technisch gesehen selbst ein Singleton ist, wie der von @CMS bereitgestellte Code zeigt. Der einzige Haken dabei ist, dass es nicht möglich ist, die Prototypkette des Konstruktors zu ändern, wenn der Konstruktor selbst anonym ist.
Beachten Sie, dass für Javascript die Konzepte "öffentlich" und "privat" nicht wie in PHP oder Java gelten. Wir haben jedoch den gleichen Effekt erzielt, indem wir die Regeln von Javascript zur Verfügbarkeit des Funktionsumfangs genutzt haben.
quelle
var a = Singleton.getInstance('foo'); var b = new a.constructor('bar');
Ich bin mir nicht sicher, warum niemand dies angesprochen hat, aber Sie können einfach Folgendes tun:
quelle
Die klarste Antwort sollte diese aus dem Buch Learning JavaScript Design Patterns von Addy Osmani sein.
quelle
Ich glaube, dies ist der einfachste / sauberste und intuitivste Weg, obwohl ES7 erforderlich ist:
Der Quellcode stammt von: adam-bien.com
quelle
new Singleton()
Was ist daran falsch?
quelle
Test = Klass; t1 = new Test(); t2 = new Test();
- Keine Möglichkeit, die Klasse umzubenennen oder einen anderen Namespace auszuwählen.kann ich meine 5 Münzen legen. Ich habe eine Konstruktorfunktion, z.
Was ich tun muss, ist, dass nur jedes von dieser CF erstellte Objekt gleich ist.
Prüfung
quelle
Ich habe festgestellt, dass das Folgende das einfachste Singleton-Muster ist, da die Verwendung des neuen Operators dieses sofort innerhalb der Funktion verfügbar macht , sodass kein Objektliteral zurückgegeben werden muss:
quelle
Hier ist das einfache Beispiel, um das Singleton-Muster in Javascript zu erklären.
quelle
Ich brauchte mehrere Singletons mit:
und so kam ich auf Folgendes:
args muss Array sein, damit dies funktioniert. Wenn Sie leere Variablen haben, übergeben Sie einfach []
Ich habe ein Fensterobjekt in der Funktion verwendet, aber ich hätte einen Parameter übergeben können, um meinen eigenen Bereich zu erstellen
Name- und Konstruktparameter sind nur Zeichenfolgen, damit window [] funktioniert. Mit einigen einfachen Typprüfungen sind jedoch auch window.name und window.construct möglich.
quelle
Wie wäre es auf diese Weise, nur versichern, dass die Klasse nicht wieder neu sein kann.
Auf diese Weise können Sie die
instanceof
Operation verwenden. Sie können auch die Prototypenkette verwenden, um die Klasse zu erben. Es handelt sich um eine reguläre Klasse, die jedoch nicht neu erstellt werden kann, wenn Sie die Instanz nur verwenden möchtengetInstance
Wenn Sie das
instance
Mitglied nicht aussetzen möchten , schließen Sie es einfach.quelle
Das Folgende ist der Ausschnitt aus meinem Durchgang, um ein Singleton-Muster zu implementieren. Dies kam mir während eines Interviewprozesses in den Sinn und ich hatte das Gefühl, dass ich das irgendwo festhalten sollte.
das gleiche kann auf meiner findet Kern Seite
quelle
quelle
Ist das nicht auch ein Singleton?
quelle
Sie können dies mit Dekoratoren wie in diesem Beispiel für TypeScript tun:
Dann verwenden Sie Ihren Singleton wie folgt:
Zum jetzigen Zeitpunkt sind Dekoratoren in JavaScript-Engines nicht ohne weiteres verfügbar. Sie müssen sicherstellen, dass in Ihrer JavaScript-Laufzeit Dekoratoren tatsächlich aktiviert sind, oder Compiler wie Babel und TypeScript verwenden.
Beachten Sie auch, dass die Singleton-Instanz "faul" erstellt wird, dh nur, wenn Sie sie zum ersten Mal verwenden.
quelle
Modulmuster: im "besser lesbaren Stil". Sie können leicht erkennen, welche Methoden öffentlich und welche privat sind
Jetzt können Sie öffentliche Methoden wie verwenden
module.method2 (); // -> Ich rufe eine private Methode über eine öffentliche Methodenwarnung auf ("hi im a private method")
http://jsfiddle.net/ncubica/xMwS9/
quelle
Singleton:
Stellen Sie sicher, dass eine Klasse nur eine Instanz hat, und stellen Sie einen globalen Zugriffspunkt darauf bereit.
Das Singleton-Muster begrenzt die Anzahl der Instanzen eines bestimmten Objekts auf nur eine. Diese einzelne Instanz wird als Singleton bezeichnet.
Das Singleton-Objekt wird als sofortige anonyme Funktion implementiert. Die Funktion wird sofort ausgeführt, indem sie in Klammern gefolgt von zwei zusätzlichen Klammern eingeschlossen wird. Es wird anonym genannt, weil es keinen Namen hat.
Beispielprogramm,
quelle
Am einfachsten / saubersten bedeutet für mich auch einfach zu verstehen und ohne Schnickschnack, wie in der Java-Version der Diskussion viel diskutiert:
Was ist ein effizienter Weg, um ein Singleton-Muster in Java zu implementieren?
Die Antwort, die aus meiner Sicht am einfachsten / saubersten dort passt, lautet:
https://stackoverflow.com/a/70824/1497139
Und es kann nur teilweise in JavaScript übersetzt werden. Einige der Unterschiede in Javascript sind:
Angesichts der neuesten ECMA-Syntax ist es jedoch möglich, Folgendes zu erreichen:
Singleton-Muster als JavaScript-Klassenbeispiel
Beispiel Verwendung
Beispiel Ergebnis
quelle
Wenn Sie in Klassen sind:
Prüfung:
quelle
Wenn Sie Klassen verwenden möchten:
Die Ausgabe für die oben genannten wird sein:
Eine andere Art, Singleton mit der Funktion zu schreiben
Die Ausgabe für die oben genannten wird sein:
quelle