如何在JavaScript中使用Revealing模块模式

时间:2011-04-13 09:46:19

标签: javascript

我偶然发现了这篇文章:JavaScript's Revealing Module Pattern。我想在我的项目中使用它。

让我们假设我有一个函数abc,我在我的主JavaScript文件中调用该函数。

这种模式会有所不同吗?有人能告诉我这种模式的基本例子吗?

10 个答案:

答案 0 :(得分:97)

一个小例子:

var revealed = function(){
   var a = [1,2,3];
   function abc(){
     return (a[0]*a[1])+a[2];
   }

   return {
      name: 'revealed',
      abcfn: abc
   }
}();

在为revealeda启动的匿名函数中,abcname对该函数是私有的。函数返回的是具有abcfn属性和abc function属性的对象文字,该属性是对abc function的引用。 a使用私有变量alert(revealed.name); //=> 'revealed' alert(revealed.abcfn()); //=> 5 (1*2+3) 。由于closures的使用,所有这一切都可以完成(函数范围内的所有内容都可以被同一函数中的其他所有内容引用)。

显示用法:

{{1}}

答案 1 :(得分:23)

  

DC = Douglas Crockford
    RMP =显示模块模式

DC和RMP之间的差异主要是组织/可读

示例在文章中提出?你究竟在问什么,因为这些东西与文件没有任何关系,而是与闭包有关。

您将所有内容放入闭包(函数)中,并仅展示您希望可访问的那些部分。 DC风格和RMP之间的区别在于,第一个函数是在不同的地方定义的,而在RMP中它们总是在同一个地方定义,然后 public <中显示 / em> object literal。

所以在DC和RMP中你有:

  • 闭包,可以定义私有部分(变量和函数)
  • 私人部分
  • 定义公开可见功能和变量(州)的公开结果

这两种模式的不同之处仅在于可读性。在DC情况下,您无法始终知道某些功能将在何处定义,但在RMP中,您始终知道所有功能都在私有部分中。

答案 2 :(得分:12)

Essential JavaScript Design Patterns For Beginners文章中描述了揭示模块模式。

答案 3 :(得分:6)

作者“Douglas Crockford创建对象的模式”所称的方法实际上是由Richard Cornford 开发的模块模式。见http://groups.google.com/group/comp.lang.javascript/msg/9f58bd11bd67d937

至于例子,有很多。阅读以下文章并关注一些链接:http://peter.michaux.ca/articles/module-pattern-provides-no-privacy-at-least-not-in-javascript-tm

答案 4 :(得分:1)

我喜欢将显示模块模式单例模式结合使用,这样我就可以使结构化代码保持模块模式的优势:

var MyFunction = function(){

    var _ = {
       Init: function(){
          _.Config.foo = "hello world";
       },
       Config:{
          foo:null
       },
       ShowAlert:function(){
          alert(_.Config.foo);
       }
    }

    return {
        Init: _.Init,
        ShowAlert: _.ShowAlert
    };
}();

MyFunction.Init();
MyFunction.ShowAlert();

我在博客上写了更多相关信息:

http://curtistimson.co.uk/js/mixing-revealing-module-and-singleton-javascript-patterns/

答案 5 :(得分:0)

对于模块外部的代码,它没什么区别。在该文章的所有3个案例中,这些方法的调用方式相同。但模块本身的结构在内部是不同的。

Crockford的模块模式和他们所谓的“揭示模块模式”在结构上几乎完全相同。唯一的区别是他们首先将方法分配给本地var,以便更具可读性。但实际上并没有什么特别之处,你的链接中有一些例子。

答案 6 :(得分:0)

揭示模块的基本概念是你有Object 封装其数据和行为:

var Module = (function(){
    var privateStuff = {};
    var publicStuff = {};

    return publicStuff;
})();

但是,使用此模式时应采用一些最佳做法。这是一个模块(&#34; Modulus&#34;),其中有一些属性用于演示,它们采用了以下一些做法:

function AbstractSomeClass(id) {
    this.id = id;
    return this;
}

var Modulus = (new (function SomeClass() {
    var thus = this;

    function NameClass(name){
        this.value = thus.name || name;
    }

    AbstractSomeClass.call(this, 998);

    this.name = 'Touring';
    this.name = ( new NameClass('Hofstadter') ).value;

    return {
        id: this.id,
        name: this.name
    };
})());

请注意(new (function SomeClass(){ ... })());语法。通过这样的new,您可以使用闭包内this关键字。如果您需要从其他类(AbstractSomeClass.call(this, 998);)继承属性,这很方便 - 但是,您仍然需要显示您希望公开的属性,例如:

return {
    id: this.id,
    name: this.name
};

另请注意,我们将this分配给thus - 这允许我们在具有自己this范围的子类内使用Parent - this({ {1}})

再一次,这些只是建议的一些惯例和最佳实践。

答案 7 :(得分:0)

以下是揭示模块模式的小例子。

它提供了一个声明私有和公共函数的工具,就像一个   这是这种模式的主要好处。如果我们不想暴露   从全局访问的一些功能然后使其私有和   其余的公开。下面是如何私有化和公开化的例子   函数。还有一件事,它是一个可自执行的代码块。

  var Calculator = (function () {

        var num1 = 10;
        var num2=5
        var _abc = function () {
            return num1 - num2;
        };

        var _mulFunc = function () {
            return num1 * num2;
        };

        var _divFunc = function () {
            return num1/num2;
        };

        return {
           //public scope
            abc: _abc,
            mulFunc:_mulFunc
         };

    })();

警报(Calculator.abc());它返回5

警报(Calculator.mulFunc());它返回50

并且__divFunc()将无法访问,因为它位于私有范围内。   我们只能访问在返回内声明的那些函数   对象   因为它是公共功能表示

答案 8 :(得分:0)

只需添加:使用这种模式,最好将全局依赖项作为参数/参数传递,以便它们是显式的。您不必执行此操作,但是乍一看就很清楚您的模块需要什么。例如:

var myModule = (function ($, loadModule) {
  "use strict";
})(jQuery, load);

在此示例中,您可以在第一行中立即看到您的模块使用jQuery和其他负责加载功能的模块。

答案 9 :(得分:0)

https://www.realmelon.com/revealing-module-design-pattern-in-javaScript/

我已经写了一篇文章。

你可以看看这个