Definition des Singleton-Musters: Stellen Sie sicher, dass eine Klasse nur eine Instanz hat, und stellen Sie einen globalen Zugriffspunkt für den Zugriff darauf bereit.
Der Singleton-Modus ist ein häufig verwendeter Modus. Es gibt einige Objekte, für die wir oft nur eines benötigen, z. B. Thread-Pools, globale Caches und Browserfensterobjekte. In der js-Entwicklung wird auch das Singleton-Muster sehr häufig verwendet. Stellen Sie sich vor, wenn wir auf die Anmeldeschaltfläche klicken, wird auf der Seite ein Anmeldefeld angezeigt, und dieses schwebende Fenster ist einzigartig. Egal wie oft wir auf die Anmeldeschaltfläche klicken, dieses schwebende Fenster wird nur einmal erstellt. Daher ist dieses schwebende Anmeldefenster für den Singleton-Modus geeignet.
1. Nutzungsszenarien des Singleton-Modus
Bevor wir einen Modus verwenden, sollten wir die Nutzungsszenarien dieses Modus kennen. Ich verwende das Singleton-Muster schon so lange und kenne es noch nicht einmal! Was sind die spezifischen Vorteile der Verwendung?
1). Sie können damit den Namensraum unterteilen (dies wird häufig verwendet)
2) Verwenden Sie die Verzweigungstechnologie, um die Unterschiede zwischen Browsern zu kapseln (ich habe das noch nie zuvor verwendet, es ist ziemlich neu)
3). Mit Hilfe des Singleton-Modus kann der Code konsistenter organisiert werden, wodurch er einfacher zu lesen und zu warten ist (dies wurde auch verwendet)
2. Das grundlegendste Singleton-Muster
Der einfachste Singleton ist eigentlich ein Objektliteral. Es organisiert eine Gruppe verwandter Methoden und Eigenschaften.
var Singleton = { attr1: true , attr2: 10 , method1 : function(){ alert('我是方法1'); }, method2 : function(){ alert('我是方法2'); } };
Dieses Objekt kann geändert werden. Sie können Eigenschaften und Methoden hinzufügen. Sie können vorhandene Mitglieder auch mit dem Löschoperator löschen. Dies verstößt tatsächlich gegen ein Prinzip des objektorientierten Designs: Klassen können erweitert werden, aber sie sollten nicht geändert werden. Wenn einige Variablen geschützt werden müssen, können sie in einem Abschluss definiert werden.
Objektliterale sind nur eine der Möglichkeiten, Singletons zu erstellen. Nicht alle Objektliterale sind Singletons, die nur zur Nachahmung assoziativer Arrays oder zum Speichern von Daten verwendet werden, sind offensichtlich keine Singletons.
3. Verwenden Sie Abschlüsse, um Singletons zu erstellen
Der Hauptzweck der Schließung ist der Schutz der Daten
// 命名空间 var BHX = {} ; BHX.Singleton = (function(){ // 添加自己的私有成员 var a1 = true ; var a2 = 10 ; var f1 = function(){ alert('f1'); } var f2 = function(){ alert('f2'); } // 把块级作用域里的执行结果赋值给我的单例对象 return { attr1: a1 , attr2: a2 , method1 : function(){ return f1(); }, method2 : function(){ return f2(); } } ; })(); alert(BHX.Singleton.attr1); BHX.Singleton.method1();
Dieser Singleton-Modus wird auch als Modulmodus bezeichnet. Dies bedeutet, dass er einen Stapel verwandter Methoden und Attribute in Modulen organisieren und die Rolle der Aufteilung des Namespace spielen kann.
4. Der Singleton-Modus wird verwendet, um den Namespace zu unterteilen
1), Änderung globaler Deklarationen verhindern
/*using a namespace*/ var BHX = {}; BHX.Singleton = { attr1: true , attr2: 10 , method1 : function(){ alert('我是方法1'); }, method2 : function(){ alert('我是方法2'); } }; BHX.Singleton.attr1; var attr1 = false;
Auf diese Weise können wir verhindern, dass attr1 bis zu einem gewissen Grad geändert wird, selbst wenn wir dieselbe Variable außerhalb deklarieren.
2), Änderung anderer Quellcodes verhindern
JavaScript-Code auf Webseiten nutzt heutzutage oft mehr als eine Quelle, wie z. B. Bibliothekscode, Werbecode und Badge-Code. Um Konflikte mit Ihrem eigenen Code zu vermeiden, können Sie ein Objekt definieren, das Ihren gesamten eigenen Code enthält.
var XGP = {}; XGP.Common = { //A singleton with common methods used by all objects and modules } XGP.ErrorCodes = { //An object literal used to store data } XGP.PageHandler = { //A singleton with page specific methods and attributes. }
3), verwendet als spezielle Codeverpackung
Auf einer Website mit vielen Webseiten werden einige Codes von allen Webseiten verwendet und normalerweise in separaten Dateien gespeichert, während einige Codes spezifisch für eine bestimmte Webseite sind und nicht anderswo verwendet werden. Am besten packen Sie beide Codetypen in ihre eigenen Singleton-Objekte.
Wir verwenden häufig Javascript, um Formularen Funktionalität hinzuzufügen. Um einen reibungslosen Abbau zu gewährleisten, ist es üblich, zunächst eine reine HTML-Seite zu erstellen, die nicht auf Javascript basiert und einen normalen Übermittlungsmechanismus verwendet, um die Aufgabe abzuschließen.
XGP.RegPage = { FORM_ID: 'reg-form', OUTPUT_ID: 'reg-result', handleSubmit: function(e){ e.preventDefault(); //stop the normal form submission var data = {}; var inputs = XGP.RegPage.formEl.getElementByTagName('input'); for(var i=0, len=inputs.length; i<len; i++){ data[inputs[i].name] = inputs[i].value; } XGP.RegPage.sendRegistration(data); }, sendRegistration: function(data){ //make an xhr request and call displayResult() when response is recieved ... }, displayResult: function(response){ XGP.RegPage.outputEl.innerHTML = response; }, init: function(){ XGP.RegPage.formEl =$(XGP.RegPage.Form_ID); XGP.RegPage.outputEl = $(XGP.RegPage.OUTPUT_ID); //hijack the form submission addEvent(XGP.RegPage.formEl, 'submit', XGP.RegPage.handleSubmit); } } //invoke initialization method after the page load addLoadEvent(XGP.RegPage.init);
5. Fauler Singleton
Das zuvor erwähnte Singleton-Muster hat noch eine weitere Gemeinsamkeit: Singleton-Objekte werden erstellt, wenn das Skript geladen wird. Bei Singletons, deren Konfiguration ressourcenintensiv oder teuer ist, ist es sinnvoller, die Instanziierung aufzuschieben, bis Sie sie verwenden müssen.
Diese Technik ist Lazy Loading.
Die Implementierungsschritte sind wie folgt:
1). Verschieben Sie den gesamten Code in die Konstruktormethode
2). Volle Kontrolle über das Aufruf-Timing (genau das, was getInstance tut)
XGP.lazyLoading = (function(){ var uniqInstance; function constructor(){ var attr = false; function method(){ } return { attrp: true, methodp: function(){ } } } return { getInstance: function(){ if(!uniqInstance){ uniqInstance = constructor(); } return uniqInstance; } } })();
6. Branchentechnologie
Branching ist eine Technik, mit der Unterschiede zwischen Browsern in dynamischen Methoden zusammengefasst werden, die zur Laufzeit festgelegt werden.
// 分支单例 (判断程序的分支 <浏览器差异的检测>) var Ext = {} ; var def = false ; Ext.More = (function(){ var objA = { // 火狐浏览器 内部的一些配置 attr1:'FF属性1' // 属性1 // 属性2 // 方法1 // 方法2 } ; var objB = { // IE浏览器 内部的一些配置 attr1:'IE属性1' // 属性1 // 属性2 // 方法1 // 方法2 } ; return (def) ?objA:objB; })(); alert(Ext.More.attr1);
Wenn xhr beispielsweise häufig auf einer Website verwendet wird, muss der Browser-Sniffing-Code bei jedem Aufruf erneut ausgeführt werden, was ernsthaft ineffizient ist. Es ist effizienter, den browserspezifischen Code einmal beim Laden des Skripts zu identifizieren. Genau das leistet die Verzweigungstechnologie. Natürlich ist die Verzweigungstechnologie nicht immer die effizientere Wahl. Es wird nur einer von zwei oder mehr Zweigen verwendet, und die anderen Zweige belegen Speicher.
Wenn Sie über den Einsatz der Branching-Technologie nachdenken, müssen Sie die Vor- und Nachteile einer Zeitverkürzung und eines höheren Speicherbedarfs abwägen.
Im Folgenden wird die Verzweigungstechnologie zur Implementierung von XHR verwendet:
var XHR = (function(){ var standard = { createXhrObj: function(){ return new XMLHttpRequest(); } }; var activeXNew = { createXhrObj: function(){ return new ActiveXObject('Msxml2.XMLHTTP'); } }; var activeXOld = { createXhrObj: function(){ return new ActiveXObject('Microsoft.XMLHTTP'); } }; var testObj; try{ testObj = standard.createXhrObj(); return testObj; }catch(e){ try{ testObj = activeXNew.createXhrObj(); return testObj; }catch(e){ try{ testObj = activeXOld.createXhrObj(); return testObj; }catch(e){ throw new Error('No XHR object found in this environment.'); } } } })();
7. Nachteile des Singleton-Modells
Da wir nun so viel über Singletons wissen, werfen wir einen Blick auf die Nachteile.
Da das Singleton-Muster einen einzigen Zugriffspunkt bietet, kann es zu einer starken Kopplung zwischen Modulen führen. Daher ist es für Unit-Tests nicht geeignet.
Zusammenfassend lässt sich sagen, dass Singletons immer noch der Definition von Namespaces und der Implementierung von Verzweigungsmethoden vorbehalten sind.
Haben Sie durch die Einführung des Singleton-Musters aus sieben verschiedenen Aspekten ein tieferes Verständnis des Singleton-Musters gewonnen? Ich hoffe, dieser Artikel kann Ihnen helfen.