Was ist der einfachste/sauberste Weg, um das Singleton-Muster in JavaScript zu implementieren?
Ich sehe nichts im OP bezüglich node.js.
Was ist der einfachste/sauberste Weg, um das Singleton-Muster in JavaScript zu implementieren?
Wenn Sie node.JS
verwenden, können Sie von node.JS Caching-Mechanismus profitieren und Ihr Singleton
wird so einfach sein:
class Singleton {
constructor() {
this.message = 'Ich bin eine Instanz';
}
}
module.exports = new Singleton();
Bitte beachten Sie, dass wir nicht die Klasse Singleton
exportieren, sondern Instanz Singleton()
.
Node.JS wird das gleiche Objekt jedes Mal zwischenspeichern und wiederverwenden, wenn es benötigt wird.
Weitere Details finden Sie hier: Node.JS und Singleton-Muster
Ich sehe auch nichts explizit über node.js, noch dass es in Vanilla JS sein muss. Daher habe ich klar hinzugefügt, dass dies für JS und node ist. Sie können es wirklich einfacher und sauberer machen, WENN Sie Node.JS verwenden! Außerdem haben, basierend auf den Upvotes, mehr Leute das hilfreich gefunden als nicht.
@iaforek Vielen Dank. Dies ist bisher der beste Weg für meinen Anwendungsfall. Sehr geschätzt.
Das folgende funktioniert in Node.js Version 6:
class Foo {
constructor(msg) {
if (Foo.singleton) {
return Foo.singleton;
}
this.msg = msg;
Foo.singleton = this;
return Foo.singleton;
}
}
Wir testen:
const f = new Foo('blah');
const d = new Foo('nope');
console.log(f); // => Foo { msg: 'blah' }
console.log(d); // => Foo { msg: 'blah' }
Das einfachste/Sauberste für mich bedeutet auch einfach zu verstehen und keine Schnörkel, wie sie in der Java-Version der Diskussion viel diskutiert werden:
Was ist ein effizienter Weg, um ein Singleton-Muster in Java zu implementieren?
Die Antwort, die meiner Meinung nach am einfachsten/saubersten passt, ist:
Jonathans Antwort zu Was ist ein effizienter Weg, um ein Singleton-Muster in Java zu implementieren?
Und es kann nur teilweise in JavaScript übersetzt werden. Einige der Unterschiede in JavaScript sind:
Aber mit der neuesten ECMA-Syntax ist es möglich, nahe dran zu kommen mit:
class Singleton {
constructor(field1,field2) {
this.field1=field1;
this.field2=field2;
Singleton.instance=this;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance=new Singleton('DefaultField1','DefaultField2');
}
return Singleton.instance;
}
}
Beispiel Verwendung
console.log(Singleton.getInstance().field1);
console.log(Singleton.getInstance().field2);
DefaultField1
DefaultField2
Ich habe gut erhaltene Antworten überprüft, aber ich denke, dass diese hier unterbeachtet ist. +1 übrigens
Ich bin neu in JavaScript und komme von Java, und muss fragen, wie verhindert wird, dass man new Singleton()
ausführt und dadurch das Singleton-Muster unterbrochen wird?
Wenn Sie Klassen verwenden möchten:
class Singleton {
constructor(name, age) {
this.name = name;
this.age = age;
if(this.constructor.instance)
return this.constructor.instance;
this.constructor.instance = this;
}
}
let x = new Singleton('s', 1);
let y = new Singleton('k', 2);
Der Output für das obige Beispiel wird sein:
console.log(x.name, x.age, y.name, y.age) // s 1 s 1
Eine andere Möglichkeit, Singleton mit einer Funktion zu schreiben
function AnotherSingleton (name,age) {
this.name = name;
this.age = age;
if(this.constructor.instance)
return this.constructor.instance;
this.constructor.instance = this;
}
let a = new AnotherSingleton('s', 1);
let b = new AnotherSingleton('k', 2);
Der Output für das obige Beispiel wird sein:
console.log(a.name, a.age, b.name, b.age) // s 1 s 1
Ich habe dieses Beispiel aus dem *JavaScript Patterns Erstellen Sie bessere Anwendungen mit Codierungs- und Entwurfsmustern Buch (von Stoyan Stefanov). Falls Sie eine einfache Implementierungsklasse wie ein Singleton-Objekt benötigen, können Sie eine sofortige Funktion wie folgt verwenden:
var Klassenname;
(function() {
var instanz;
Klassenname = function Klassenname() {
// Wenn die private Instanzvariable bereits initialisiert ist, geben Sie eine Referenz zurück
if(instanz) {
return instanz;
}
// Wenn die Instanz nicht erstellt wurde, speichern Sie einen Verweis auf die ursprüngliche Referenz
// zur privaten Instanzvariable.
instanz = this;
// Alle Konstruktorinitialisierungen werden hier erfolgen
// z.B.:
this.eineEigenschaft = 0;
this.eineMethode = function() {
// Hier eine Aktion
};
};
}());
Und Sie können dieses Beispiel mit folgendem Testfall überprüfen:
// Erweiterung der definierten Klasse wie ein Singleton-Objekt unter Verwendung der neuen Prototyp-Eigenschaft
Klassenname.prototype.nichts = true;
var obj_1 = new Klassenname();
// Erweiterung der definierten Klasse wie ein Singleton-Objekt unter Verwendung der neuen Prototyp-Eigenschaft
Klassenname.prototype.alles = true;
var obj_2 = new Klassenname();
// Test macht deutlich, dass diese beiden Objekte auf dieselbe Instanz zeigen
console.log(obj_1 === obj_2); // Ergebnis ist true und es zeigt auf dasselbe Instanzobjekt
// Alle Prototyp-Eigenschaften funktionieren
// egal wann sie definiert wurden
console.log(obj_1.nichts && obj_1.alles
&& obj_2.nichts && obj_2.alles); // Ergebnis true
// Werte von Eigenschaften, die im Konstruktor definiert sind
console.log(obj_1.eineEigenschaft); // Ausgabe 0
console.log(obj_2.eineEigenschaft); // Ausgabe 0
// Änderung des Eigenschaftswerts
obj_1.eineEigenschaft = 1;
console.log(obj_1.eineEigenschaft); // Ausgabe 1
console.log(obj_2.eineEigenschaft); // Ausgabe 1
console.log(obj_1.constructor === Klassenname); // Ausgabe true
Dieser Ansatz besteht alle Testfälle, während eine private statische Implementierung scheitert, wenn eine Prototyperweiterung verwendet wird (es kann behoben werden, aber es wird nicht einfach sein) und eine öffentliche statische Implementierung weniger ratsam ist, da eine Instanz öffentlich zugänglich ist.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
34 Stimmen
Downvote dafür, dass die akzeptierte Antwort überhaupt kein Singleton ist. Es ist einfach eine globale Variable.
7 Stimmen
Dies ist eine Menge Informationen, aber es legt wirklich die Unterschiede zwischen den verschiedenen JS-Designpatterns dar. Es hat mir sehr geholfen: addyosmani.com/resources/essentialjsdesignpatterns/book