如何在JavaScript中使用显示模块模式

如何在JavaScript中使用显示模块模式,javascript,Javascript,我偶然发现了这个帖子:。我想在我的项目中使用它 让我们假设我有一个函数abc,我正在主JavaScript文件中调用该函数 这种模式会让事情有所不同吗?有人能给我看一下这个模式的基本示例吗?本文中对模块模式的描述非常好。对于模块外的代码来说,没有什么区别。在本文中的所有3种情况下,方法的调用方式都是相同的。但是模块本身的结构在内部是不同的 Crockford的模块模式和他们所谓的“揭示模块模式”在结构上几乎是一样的。唯一的区别是,它们首先将方法分配给一个局部变量,以便更具可读性。但这并没有什么特

我偶然发现了这个帖子:。我想在我的项目中使用它

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


这种模式会让事情有所不同吗?有人能给我看一下这个模式的基本示例吗?

本文中对模块模式的描述非常好。

对于模块外的代码来说,没有什么区别。在本文中的所有3种情况下,方法的调用方式都是相同的。但是模块本身的结构在内部是不同的

Crockford的模块模式和他们所谓的“揭示模块模式”在结构上几乎是一样的。唯一的区别是,它们首先将方法分配给一个局部变量,以便更具可读性。但这并没有什么特别之处,你的链接中有一些例子

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

DC和RMP之间的差异主要在于组织/可读性 文章本身给出了一个例子?你到底在问什么,因为这些东西与文件无关,而与闭包有关

您将所有内容都放在一个闭包(函数)中,并且只公开希望访问的部分。DC样式和RMP之间的区别在于,在第一个样式中,函数定义在不同的位置,而在RMP中,它们总是定义在同一位置,然后在公共对象文本中显示

因此,在DC和RMP中,您有:

  • 使定义私有部分(变量和函数)成为可能的闭包
  • 私人部分
  • 定义公共可见功能和变量的公共结果(状态)
这两种模式仅在可读性上有所不同。在DC情况下,您无法始终知道某些功能将在何处定义,但在RMP中,您始终知道所有内容都在私有部分。

一个小示例:

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

   return {
      name: 'revealed',
      abcfn: abc
   }
}();
在初始化以提供值的匿名函数中,
a
abc
是该函数的私有函数。函数返回的是一个带有
name
属性和
abcfn
属性的对象文本,该属性是对
abc函数的引用。
abc函数
使用私有变量
a
。这一切都可以通过使用实现(函数范围内的所有内容都可以被同一函数中的其他内容引用)

显示用法:

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

作者称之为“Douglas Crockford创建对象的模式”的方法实际上是主要由Richard Cornford等人开发的模块模式


举个例子,有很多。阅读以下文章并点击一些链接:

揭示模块的基本概念是,您有一个
对象,它封装了它的数据和行为:

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

    return publicStuff;
})();
但是,在使用此模式时,您应该采用一些最佳实践。下面是一个模块(“
模数
”),为了演示,它具有一些属性,采用了以下一些做法:

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
    };
})());
注意
(新的(函数SomeClass(){…})()语法。这样使用
new
可以在闭包中使用
this
关键字。如果您需要从另一个类继承属性(
AbstractSomeClass.call(This,998);
),这很方便--但是,您仍然需要显示希望公开的属性,例如:

return {
    id: this.id,
    name: this.name
};
还请注意,我们将
this
分配给
this
——这允许我们在子类内部使用父类-
this
,该子类有自己的
this
作用域(
this.value=this.name | | name;


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

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

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();
我在我的博客上写了更多关于这方面的信息:


以下是显示模块模式的小示例。

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

  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()将不可访问,因为它位于私有作用域中。 我们只能访问return中声明的函数 对象
因为它是公共函数表示法

只想添加:使用这种模式,最好将全局依赖项作为参数/参数传递,以便它们是显式的。您不必这样做,但这一点从第一眼就可以清楚地看出您的模块需要什么。例如:

var myModule = (function ($, loadModule) {
  "use strict";
})(jQuery, load);
在本例中,您可以立即在第一行看到您的模块使用jQuery和其他一些负责加载功能的模块。

我写了一篇关于它的文章


你可以看看这个

我重新编辑了我的帖子,如果还有任何问题,请告诉我:)有趣的是,这些东西是如何随时间变化的。“透露”版本已经被大卫·马克(名人)使用了一段时间,我对“不透露”版本没有任何问题,所以我使用它。:-)这种模式改变了我的生活!我知道这很旧,但是abc()的返回值缺少一个括号=]当您可以使用最终模块模式时,为什么要使用显示模块模式?我如何创建一个新的显示实例?@NeonWarge:你没有。