Le modèle de module est un modèle de conception relativement populaire. Il peut encapsuler des variables privées, des méthodes et des états via des accolades. En empaquetant ces contenus, les objets globaux ne sont généralement pas accessibles directement dans ce modèle de conception. est renvoyé et tous les autres contenus sont encapsulés comme privés.
De plus, ce mode est similaire à l'expression de fonction auto-exécutable. La seule différence est que le module renvoie un objet, tandis que l'expression de fonction auto-exécutable renvoie une fonction.
Comme nous le savons tous, JavaScript n'a pas de modificateurs d'accès comme les autres langages. Il ne peut pas déclarer de modificateurs privés et publics pour chaque champ ou méthode. Alors, comment implémenter ce modèle ? Il s'agit de renvoyer un objet contenant des méthodes publiques. Ces méthodes ont la capacité d'appeler des objets internes.
Regardez le code suivant. Ce code est un code auto-exécutable. La déclaration inclut un objet global basketModule. Le tableau panier est privé, donc l'ensemble de votre programme ne peut pas accéder à ce tableau privé en même temps. nous avons renvoyé un objet qui contient trois méthodes (telles que addItem, getItemCount, getTotal). Ces trois méthodes peuvent accéder au tableau du panier privé.
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; } } }());
Notez également que l'objet que nous renvoyons est directement affecté à basketModule, nous pouvons donc l'utiliser comme suit :
//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)
Comment le faire dans diverses bibliothèques populaires (telles que Dojo, jQuery) ?
Dojo
Dojo essaie d'utiliser dojo.declare pour fournir une déclaration de style classe. Nous pouvons l'utiliser pour implémenter le mode Module, par exemple, si vous le souhaitez. pour stocker l'espace de noms Déclarez l'objet panier ci-dessous, vous pouvez alors faire ceci :
//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(); } }; }()));
Utilisez-le en conjonction avec dojo.provide, qui est très puissant.
YUI
Le code suivant est l'implémentation originale de 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
Il existe de nombreuses implémentations du modèle Module dans jQuery Regardons un autre exemple. Une fonction de bibliothèque déclare une nouvelle bibliothèque, puis lorsque la bibliothèque est créée, elle est automatiquement ajoutée au document. .ready Exécute la méthode init.
function library(module) { $(function() { if (module.init) { module.init(); } }); return module; } var myLibrary = library(function() { return { init: function() { /*implementation*/ } }; }());
Valeur faciale de l'objet
Utilisations de la valeur faciale de l'objet Déclaration entre accolades, et il n'est pas nécessaire d'utiliser le nouveau mot-clé lors de son utilisation. Si vous ne vous souciez pas beaucoup du caractère public/privé des champs d'attribut dans un module, vous pouvez utiliser cette méthode, mais veuillez noter que cette méthode est. différent de JSON. Visage de l'objet : 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
Je ne dirai pas grand chose sur l'introduction de CommonJS ici. Oui, de nombreux articles l'ont déjà présenté. Ce que nous voulons mentionner ici, c'est qu'il y a deux paramètres importants dans la norme CommonJS, exports et require Exports représentent les modules à charger, et require représente ce dont ces modules chargés ont besoin. pour dépendre d'autres modules, il doit également être chargé.
/* 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)});
Il existe de nombreuses implémentations de chargement de modules standard CommonJS. Celle que je préfère est RequireJS. Peut-il très bien charger les modules et les modules dépendants associés ? exemple simple, si nous avons besoin de convertir une image en code ASCII, nous chargeons d'abord le module encodeur puis obtenons sa méthode encodeToASCII Théoriquement le code devrait être le suivant :
var encodeToASCII = require("encoder").encodeToASCII; exports.encodeSomeSource = function(){ //其它操作以后,然后调用encodeToASCII }
Mais le code ci-dessus ne fonctionne pas, car la fonction encodeToASCII n'est pas attachée à l'objet window, elle ne peut donc pas être utilisée. Le futur code doit être amélioré comme ceci :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!