【问题标题】:How to use Revealing module pattern in JavaScript如何在 JavaScript 中使用 Revealing 模块模式
【发布时间】:2011-08-04 13:43:44
【问题描述】:

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

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

这种模式会让事情变得不同吗?谁能给我看一个这种模式的基本例子吗?

【问题讨论】:

标签: javascript


【解决方案1】:

一个小例子:

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

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

在初始化为给revealed 一个值的匿名函数中,aabc 是该函数私有的。该函数返回的是一个带有name 属性和abcfn 属性的对象字面量,该属性是对abc function 的引用。 abc function 使用私有变量 a。这一切都可以通过使用closures 来完成(函数范围内的所有内容都可以被同一函数中的所有其他内容引用)。

显示用法:

alert(revealed.name);    //=> 'revealed'
alert(revealed.abcfn()); //=> 5 (1*2+3)

【讨论】:

  • 这种模式改变了我的生活!
  • 我知道这是旧的,但是 abc() 的返回值缺少括号 =]
  • 当您可以使用确定模块模式时,为什么要使用显示模块模式? github.com/tfmontague/definitive-module-pattern
  • 如何创建新的显示实例?
  • @NeonWarge:你不知道。该函数不是构造函数。它返回一个对象字面量,其中aabc 被关闭。
【解决方案2】:

DC = 道格拉斯·克罗克福德
RMP = 揭示模块模式

DC 和 RMP 的区别主要在于组织性/可读性

示例是在文章本身中介绍的?你到底在问什么,因为这些东西与文件没有任何关系,而是与闭包有关。

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

所以在 DC 和 RMP 中你有:

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

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

【讨论】:

【解决方案3】:

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

【讨论】:

    【解决方案4】:

    作者所说的“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

    【讨论】:

    • 我重新发了帖子,如果还有问题请告诉我:)
    • 有趣的是这些东西如何随着时间的推移而变化。大卫马克(MyLibrary成名)使用“揭示”版本有一段时间了,我对“非揭示”版本没有任何问题,所以我使用它。 :-)
    【解决方案5】:

    我喜欢混合使用显示模块模式单例模式,这样我就可以保留结构化代码并享受模块模式的好处:

    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/

    【讨论】:

      【解决方案6】:

      只是想补充一点:使用这种模式,将全局依赖项作为参数/参数传递是很好的,这样它们就很明确了。您不必这样做,但这从第一眼就很清楚您的模块需要什么。例如:

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

      在这个例子中,你可以在第一行看到你的模块使用了 jQuery 和其他一些负责加载功能的模块。

      【讨论】:

        【解决方案7】:

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

        我已经写了一篇文章。

        你可以看看这个

        【讨论】:

          【解决方案8】:

          对于模块外的代码来说,差别不大。在那篇文章中的所有 3 个案例中,方法的调用方式都相同。但是模块本身的结构在内部是不同的。

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

          【讨论】:

          【解决方案9】:

          显示模块的基本概念是您有一个Object,它封装它的数据和行为:

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

          但是,在使用此模式时,您应该采用一些最佳做法。下面是一个模块 ("Modulus"),其中包含一些用于演示的属性,它采用了其中的一些做法:

          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 关键字inside。如果您需要从另一个类 (AbstractSomeClass.call(this, 998);) 继承属性,这很方便——但是,您仍然需要显示您希望公开的属性,例如:

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

          还请注意,我们将 this 分配给 thus ——这允许我们在具有自己的 this 范围 (this.value = thus.name || name;) 的子类中使用 Parent-this

          再次重申,这些只是建议的一些约定和最佳做法。

          【讨论】:

            【解决方案10】:

            这是揭示模块模式的小例子。

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

              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

            alert(Calculator.mulFunc());它返回 50

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2023-03-22
              • 1970-01-01
              • 2023-03-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多