Je lis le livre Learning JavaScript Design Patterns récemment. Ce que je ne comprends pas, c'est la différence entre modèle de module et modèle de module révélateur. Je pense qu'ils sont la même chose. Tout le monde peut donner un exemple?
Il existe au moins trois manières différentes d'implémenter le modèle de module, mais le modèle de module de révélation est le seul descendant de modèle de module qui porte un nom officiel.
Le modèle de module doit satisfaire aux exigences suivantes:
Mais il y a beaucoup d'ambiguïté dans cette définition. En résolvant l'ambiguïté différemment, vous obtenez des variantes du modèle de module.
Le modèle de module révélé est la plus célèbre et la plus populaire des variantes de modèle de module. Il présente un certain nombre d'avantages par rapport aux autres alternatives, telles que
Le PGR remplit trois conditions supplémentaires en plus de celles de l'original:
L'exemple suivant montre comment il est utilisé
var welcomeModule = (function(){
var name = "John";
var hello = function(){ console.log("Hello, " + name + "!");}
var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return {
name: name,
sayHello: hello,
sayWelcome: welcome
}
})();
Si vous souhaitez rendre name
et sayHello
private, il vous suffit de commenter les lignes appropriées dans l'objet de retour.
var welcomeModule = (function(){
var name = "John";
var hello = function(){ console.log("Hello, " + name + "!");}
var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return {
//name: name,
//sayHello: hello,
sayWelcome: welcome
}
})();
C'est probablement la variante la plus ancienne du modèle de module. Contrairement à RMP, il n’ya pas de nom officiel sexy pour cette variante.
Il répond aux conditions suivantes, en plus de l'original:
this
, dans la mesure du possible.Dans l'exemple suivant, vous pouvez voir comment, contrairement à RMP, les définitions de fonction sont en réalité dans le littéral de l'objet de retour et que les références aux membres sont qualifiées par this
.
var welcomeModule = (function(){
return {
name: "John",
sayHello: function(){ console.log("Hello, " + this.name + "!");}
sayWelcome: function() { console.log( this.hello() + " Welcome to StackOverflow!");}
}
})();
Notez que pour que name
et sayHello
soient privés, les références pointant vers name
et sayHello
dans les différentes définitions de corps de fonction doivent également être modifiées.
var welcomeModule = (function(){
var name: "John";
var sayHello = function(){ console.log("Hello, " + name + "!");};
return {
//name: "John",
//sayHello: function(){ console.log("Hello, " + this.name + "!");}
sayWelcome: function() { console.log( hello() + " Welcome to StackOverflow!");}
}
})();
Cette variante n'a pas non plus de nom officiel.
Il répond aux conditions suivantes, en plus de l'original:
En utilisant notre ancien exemple, vous pouvez voir que des membres du public sont directement ajoutés à l'objet stub.
var welcomeModule = (function(){
var stub = {};
stub.name = "John";
stub.sayHello = function(){ console.log("Hello, " + stub.name + "!");}
stub.sayWelcome = function() { console.log( stub.hello() + " Welcome to StackOverflow!");}
return stub;
})();
Si vous souhaitez que name
et sayHello
soient privés comme auparavant, vous devez modifier les références aux membres maintenant privés.
var welcomeModule = (function(){
var stub = {};
var name = "John";
var sayHello = function(){ console.log("Hello, " + name + "!");}
stub.sayWelcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
return stub;
})();
Les différences entre le modèle de module de révélation et les autres variantes du modèle de module résident principalement dans la façon dont les membres publics sont référencés. En conséquence, RMP est beaucoup plus facile à utiliser et à modifier, ce qui explique sa popularité. Cependant, ces avantages ont un coût énorme (à mon avis), auquel Addy Osmani fait allusion dans son post sur Modèle de module révélateur ,
Un inconvénient de ce modèle est que si une fonction privée fait référence à une fonction publique, cette fonction publique ne peut pas être remplacée si un correctif est nécessaire. En effet, la fonction privée continuera à faire référence à l'implémentation privée et le modèle ne s'applique pas aux membres publics, mais uniquement aux fonctions.
Les membres d'objets publics qui font référence à des variables privées sont également soumis aux remarques ci-dessus relatives aux règles de non-correctif.
En conséquence, les modules créés avec le modèle de module de révélation peuvent être plus fragiles que ceux créés avec le modèle de module d'origine. Il convient donc de prendre des précautions lors de l'utilisation.
Réponse courte, Dans le modèle de module, nous définissons des fonctions dans le renvoi d'objet.
Dans le modèle Révéler le module, nous définissons les fonctions dans la zone de fermeture et utilisons uniquement les noms de variables dans l'objet renvoyé.
Cela simplifie le code et présente de nombreux autres avantages.
Essayez juste de faire quelque chose en vous basant sur la réponse du meilleur commentaire. Peut-être est-il plus sûr d'appeler une fonction privée en lui passantthis, de sorte que cette fonction privée pourrait référencer une fonction publique avecthisvariable.
J'ai créé un modèle de module révélateur avec le code suivant.
var HTMLChanger = (function () {
var privateFunc = function () {
this.sayHello();
}
var hello = function () {
console.log('say Hello');
}
var callPrivate = function () {
privateFunc.call(this);
}
return {
sayHello: hello,
callPrivate: callPrivate
};
})();
HTMLChanger.callPrivate();
//say Hello
HTMLChanger.sayHello = function() { console.log('say Hi!') };
HTMLChanger.callPrivate();
//say Hi!
Comme vous pouvez le constater, nous pouvons remplacer un membre public.