揭示模块模式的轻微变化

时间:2014-12-10 09:12:51

标签: design-patterns javascript revealing-module-pattern

使用是否是好习惯,而不是Revealing Module Pattern ...

var MyModule = ( function() {
  function Method1() { alert( 'method1' ); }
  function Method2() { Method1(); alert( 'method2' ); }
  function Method3() { Method1(); alert( 'method3' ); }
  function Method4() { Method1(); alert( 'method4' ); }
  return { Method1 : Method1,    // these
           Method2 : Method2,    // lines
           Method3 : Method3,    // are 
           Method4 : Method4 };  // redundant...
} )();

MyModule.Method1(); 
MyModule.Method2();

......这种轻微的变化:

var MyModule = {};
( function() {
  var Method1 = MyModule.Method1 = function () { alert( 'method1' ); };
  var Method2 = MyModule.Method2 = function () { Method1(); alert( 'method2' ); };
  var Method3 = MyModule.Method3 = function () { Method1(); alert( 'method3' ); };
  var Method4 = MyModule.Method4 = function () { Method1(); alert( 'method4' ); };
} )();

MyModule.Method1();
MyModule.Method2();

最后是100%相同吗?这会被视为良好做法吗?

3 个答案:

答案 0 :(得分:1)

  

最后是100%相同吗?

最终结果是一样的。

  

这会被视为良好做法吗?

这主要是一个意见问题。您的示例是RMP中的两个变体中的两个,都是有效的。

常见的第三种变体与您的第二种变体类似,但具有特定目的:

var MyModule = function(mod) {
  var Method1 = mod.Method1 = function () { alert( 'method1' ); };
  var Method2 = mod.Method2 = function () { Method1(); alert( 'method2' ); };
  var Method3 = mod.Method3 = function () { Method1(); alert( 'method3' ); };
  var Method4 = mod.Method4 = function () { Method1(); alert( 'method4' ); };
  return mod;
}(typeof MyModule === "undefined" ? {} : MyModule);

目的是允许添加已定义的模块,但如果尚未定义则创建它。

答案 1 :(得分:1)

不一样。如果您随时重命名模块或希望以不同的名称使用它,您将无法使用。

此外,通过返回数组末尾的对象,可以非常清楚地从对象中暴露出来的内容。

答案 2 :(得分:1)

您的第一个和第二个变体不一样。第一个是我称之为“自足的”IIFE-- IIFE的主体在没有提供有关IIFE之外的世界的任何信息的情况下完成其工作。您的第二个变体假定外部世界中有MyModule个对象。虽然这是一个很小的假设,但我更愿意以独立的方式编写所有的IIFE。

第二种变体可以通过稍作修改自成一体:

var MyModule = {};
( function(MyModule) {
  var Method1 = MyModule.Method1 = function () { alert( 'method1' ); };
  var Method2 = MyModule.Method2 = function () { Method1(); alert( 'method2' ); };
  var Method3 = MyModule.Method3 = function () { Method1(); alert( 'method3' ); };
  var Method4 = MyModule.Method4 = function () { Method1(); alert( 'method4' ); };
} )(MyModule);

MyModule.Method1();
MyModule.Method2();

通过将创建的外部对象作为参数传递给IIF,IIFE中的代码不再对外部世界做出假设,并且可以更容易地移动到代码库内的不同位置。

但是,你也问了

  

这会被视为良好做法吗?

我对此的回答是你根本不应该使用Revealing Module Pattern !揭示模块模式有一个重要的defect使我认为它是anti-pattern,所以我建议不要使用它。坚持原始模块模式,而不是Revealing Module。