原文:https://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript

现在,我们已经更熟悉模块模式一些了,让我们来看稍微改进的版本 - Christian Heilmann 提出的揭示模块模式(Revealing Module Pattern)。

揭示模式的出现是由于 Heilmann 对于我们想从另一个公共方法调用一个公共方法或者访问公共变量时必须重复主对象的名称感到沮丧。他同样不喜欢模块模式需要把他想公开的部分转换成对象字面量的形式。

他努力的结果是一个更新的模式,我们可以简单地定义私有域内所有的函数和变量,返回一个匿名对象,其中包含了指向我们希望公开的私有功能的指针。

下面的示例演示了我们如果使用揭示模式:

  1. var myRevealingModule = (function() {
  2. var privateVar = 'Ben Cherry',
  3. publicVar = 'Hey there!';
  4. function privateFunction() {
  5. console.log('Name:' + privateVar);
  6. }
  7. function publicSetName(strName) {
  8. privateVar = strName;
  9. }
  10. function publicGetName() {
  11. privateFunction();
  12. }
  13. // 暴露公共的指针指向私有函数和属性
  14. return {
  15. setName: publicSetName,
  16. greeting: publicVar,
  17. getName: publicGetName
  18. };
  19. })();
  20. myRevealingModule.setName('Paul Kinlan');

如果我们愿意,该模式还可以用更具体的命名方案来展示私有函数和属性:

  1. var myRevealingModule = (function() {
  2. var privateCounter = 0;
  3. function privateFunction() {
  4. privateCounter++;
  5. }
  6. function publicFunction() {
  7. publicIncrement();
  8. }
  9. function publicIncrement() {
  10. privateFunction();
  11. }
  12. function publicGetCount() {
  13. return privateCounter;
  14. }
  15. // 暴露私有方法和属性的公开指针
  16. return {
  17. start: publicFunction,
  18. increment: publicIncrement,
  19. count: publicGetCount
  20. };
  21. })();
  22. myRevealingModule.start();

优点

这个模式让我们脚本的语法更加一致。它还使得在模块结尾处我们可以更清晰的知道我们那些函数和变量可以被公开访问,从而增强了可读性。

缺点

这个模式的一个缺点就是如果一个私有函数引用公开函数,当需要补丁时,则无法覆盖公共函数。这是因为私有函数仍是引用私有实现,并且该模式不适用于公开成员,仅适用于函数。

引用私有变量的公开对象成员同样也受上述无补丁规则约束。

因此,使用揭示模式创建的模块相比那些使用原始模块模式创建的模块更脆弱,所以小心使用。