Modulmuster sind ein relativ beliebtes Entwurfsmuster. Durch das Packen dieser Inhalte kann in diesem Entwurfsmuster im Allgemeinen nicht direkt darauf zugegriffen werden wird zurückgegeben und alle anderen Inhalte werden als privat gekapselt.
Darüber hinaus ähnelt dieser Modus dem selbstausführenden Funktionsausdruck. Der einzige Unterschied besteht darin, dass das Modul ein Objekt zurückgibt, während der selbstausführende Funktionsausdruck eine Funktion zurückgibt.
Wie wir alle wissen, verfügt JavaScript nicht über Zugriffsmodifikatoren. Es kann nicht für jedes Feld oder jede Methode private und öffentliche Modifikatoren deklarieren. Das heißt, ein Objekt zurückzugeben, das einige öffentliche Methoden enthält. Diese Methoden können interne Objekte aufrufen.
Sehen Sie sich den folgenden Code an. Die Deklaration enthält ein globales Korbmodul, sodass Ihr gesamtes Programm nicht gleichzeitig darauf zugreifen kann. Wir haben ein Objekt zurückgegeben, das drei Methoden enthält (z. B. addItem, getItemCount, getTotal). Diese drei Methoden können auf das private Korbarray zugreifen.
var basketModule = (function() { var basket = []; //private return { //exposed to public addItem: function(values) { basket.push(values); }, getItemCount: function() { return basket.length; }, getTotal: function(){ var q = this.getItemCount(),p=0; while(q--){ p+= basket[q].price; } return p; } } }());
Beachten Sie außerdem, dass das von uns zurückgegebene Objekt direkt dem Korbmodul zugewiesen ist, sodass wir es wie folgt verwenden können:
//basketModule is an object with properties which can also be methods basketModule.addItem({item:'bread',price:0.5}); basketModule.addItem({item:'butter',price:0.3}); console.log(basketModule.getItemCount()); console.log(basketModule.getTotal()); //however, the following will not work: console.log(basketModule.basket);// (undefined as not inside the returned object) console.log(basket); //(only exists within the scope of the closure)
Wie geht das in verschiedenen gängigen Bibliotheken (wie Dojo, jQuery)?
Dojo
Dojo versucht, dojo.declare zu verwenden, um eine Deklaration im Klassenstil bereitzustellen. Wenn Sie möchten, können wir damit beispielsweise den Modulmodus implementieren Um den Namespace zu speichern, deklarieren Sie das folgende Korbobjekt. Dann können Sie Folgendes tun:
//traditional way var store = window.store || {}; store.basket = store.basket || {}; //using dojo.setObject dojo.setObject("store.basket.object", (function() { var basket = []; function privateMethod() { console.log(basket); } return { publicMethod: function(){ privateMethod(); } }; }()));
Verwenden Sie es in Verbindung mit dojo.provide, was sehr leistungsstark ist.
YUI
Der folgende Code ist die ursprüngliche Implementierung von YUI:
YAHOO.store.basket = function () { //"private" variables: var myPrivateVar = "I can be accessed only within YAHOO.store.basket ."; //"private" method: var myPrivateMethod = function () { YAHOO.log("I can be accessed only from within YAHOO.store.basket"); } return { myPublicProperty: "I'm a public property.", myPublicMethod: function () { YAHOO.log("I'm a public method."); //Within basket, I can access "private" vars and methods: YAHOO.log(myPrivateVar); YAHOO.log(myPrivateMethod()); //The native scope of myPublicMethod is store so we can //access public members using "this": YAHOO.log(this.myPublicProperty); } }; } ();
jQuery
Es gibt viele Implementierungen des Modulmusters in jQuery. Schauen wir uns ein anderes Beispiel an. Eine Bibliotheksfunktion deklariert eine neue Bibliothek und wird dann automatisch zum Dokument hinzugefügt .ready Führen Sie die Init-Methode aus.
function library(module) { $(function() { if (module.init) { module.init(); } }); return module; } var myLibrary = library(function() { return { init: function() { /*implementation*/ } }; }());
Objekt-Selbstgesichtswert
Objekt-Selbstgesichtswert verwendet Klammern Deklaration, und es ist nicht erforderlich, das Schlüsselwort new zu verwenden, wenn Sie es verwenden. Wenn Ihnen die Öffentlichkeit/Privatsphäre der Attributfelder in einem Modul nicht so wichtig ist, können Sie diese Methode verwenden. Beachten Sie jedoch, dass dies der Fall ist anders als JSON. Objekt-Selbstgesicht: var item={name: „tom“, value:123} JSON: var item={“name“: „tom“, „value“:123}.
var myModule = { myProperty: 'someValue', //object literals can contain properties and methods. //here, another object is defined for configuration //purposes: myConfig: { useCaching: true, language: 'en' }, //a very basic method myMethod: function () { console.log('I can haz functionality?'); }, //output a value based on current configuration myMethod2: function () { console.log('Caching is:' + (this.myConfig.useCaching) ? 'enabled' : 'disabled'); }, //override the current configuration myMethod3: function (newConfig) { if (typeof newConfig == 'object') { this.myConfig = newConfig; console.log(this.myConfig.language); } } }; myModule.myMethod(); //I can haz functionality myModule.myMethod2(); //outputs enabled myModule.myMethod3({ language: 'fr', useCaching: false }); //fr
CommonJS
Ich werde nicht viel über die Einführung von sagen CommonJS hier. Ja, wir möchten hier erwähnen, dass es zwei wichtige Parameter im CommonJS-Standard gibt: „Exports“ und „Require“ stellen die zu ladenden Module dar Um von anderen Modulen abhängig zu sein, muss es ebenfalls geladen werden.
/* Example of achieving compatibility with AMD and standard CommonJS by putting boilerplate around the standard CommonJS module format: */ (function(define){ define(function(require,exports){ // module contents var dep1 = require("dep1"); exports.someExportedFunction = function(){...}; //... }); })(typeof define=="function"?define:function(factory){factory(require,exports)});
Es gibt viele CommonJS-Standard-Modulladeimplementierungen. Die, die ich bevorzuge, ist RequireJS. Kann es Module und verwandte abhängige Module sehr gut laden? Einfaches Beispiel: Wenn wir ein Bild in ASCII-Code konvertieren müssen, laden wir zuerst das Encoder-Modul und erhalten dann seine encodeToASCII-Methode. Theoretisch sollte der Code wie folgt aussehen:
var encodeToASCII = require("encoder").encodeToASCII; exports.encodeSomeSource = function(){ //其它操作以后,然后调用encodeToASCII }
Der obige Code funktioniert jedoch nicht, da die Funktion encodeToASCII nicht an das Fensterobjekt angehängt ist und daher nicht verwendet werden kann. Der zukünftige Code muss wie folgt verbessert werden:
define(function(require, exports, module) { var encodeToASCII = require("encoder").encodeToASCII; exports.encodeSomeSource = function(){ //process then call encodeToASCII } });
Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung von Anwendungsbeispielen des Modulmusters im JavaScript-Architekturdesign. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!