当前位置: 首页 > 面试题库 >

JavaScript设计模式:模块模式和显示模块模式之间的区别?

史弘致
2023-03-14
问题内容

我最近正在读《 学习JavaScript设计模式》 这本书。我没有得到的是模块模式和显示模块模式之间的区别。我觉得他们是同一回事。有人可以举一个例子吗?


问题答案:

至少有三种不同的方法来实现模块模式,但是显示模块模式是唯一具有正式名称的模块模式后代。

基本模块模式

模块模式必须满足以下条件:

  • 私有成员住在封闭中。
  • 公共成员暴露在返回对象中。

但是这个定义有很多歧义。通过以不同方式解决歧义,您可以获得模块模式的变体。

显示模块模式

显示模块模式是“模块模式”变体中最著名和最受欢迎的模块。与其他替代方案相比,它具有许多优势,例如

  • 重命名公共功能而不更改功能主体。
  • 通过修改一行来将成员从公共更改为私人,反之亦然,而无需更改功能主体。

RMP除原始条件外还满足其他三个条件:

  • 闭包中定义了所有公共或私有成员。
  • 返回对象是没有函数定义的对象文字。所有右手表达式都是闭包变量
  • 所有引用都是通过闭包变量,而不是返回对象。

以下示例显示了其用法

var welcomeModule = (function(){
  var name = "John";
  var hello = function(){ console.log("Hello, " + name + "!");}
  var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
  return {
    name: name,
    sayHello: hello,
    sayWelcome: welcome
  }
})();

如果你想使namesayHello私有的,你只需要注释掉返回对象相应行。

var welcomeModule = (function(){
  var name = "John";
  var hello = function(){ console.log("Hello, " + name + "!");}
  var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
  return {
    //name: name,
    //sayHello: hello,
    sayWelcome: welcome
  }
})();

具有对象文字的模块模式

这可能是模块模式的最旧的变体。与RMP不同,此变体没有性感的正式名称。

除了原始条件外,它还满足以下条件:

  • 私有成员在闭包中定义。
  • 公共成员在返回对象文字中定义。
  • this只要有可能,都通过引用公共成员。

在下面的示例中,您可以看到与RMP相比,函数定义实际上是在返回对象文字中,而对成员的引用由限定this

var welcomeModule = (function(){
  return {
    name: "John",
    sayHello: function(){ console.log("Hello, " + this.name + "!");}
    sayWelcome: function() { console.log( this.hello() + " Welcome to StackOverflow!");}
  }
})();

请注意,与RMP一样,为了生成namesayHello私有化,指向name和指向sayHello各种函数体定义的引用也必须更改。

var welcomeModule = (function(){
  var name: "John";
  var sayHello = function(){ console.log("Hello, " + name + "!");};
  return {
    //name: "John",
    //sayHello: function(){ console.log("Hello, " + this.name + "!");}
    sayWelcome: function() { console.log( hello() + " Welcome to StackOverflow!");}
  }
})();

带返回对象存根的模块模式

此变体也没有正式名称。

除了原始条件外,它还满足以下条件:

  • 开头定义了一个空的返回对象存根。
  • 私有成员在闭包中定义。
  • 公开成员定义为存根的成员
  • 通过存根对象引用公共成员

使用我们的旧示例,您可以看到公共成员被直接添加到存根对象中。

var welcomeModule = (function(){
  var stub = {};
  stub.name = "John";
  stub.sayHello = function(){ console.log("Hello, " + stub.name + "!");}
  stub.sayWelcome = function() { console.log( stub.hello() + " Welcome to StackOverflow!");}
  return stub;
})();

如果你想namesayHello私人像以前一样,到现在,私有成员的引用必须改变。

var welcomeModule = (function(){
  var stub = {};
  var name = "John";
  var sayHello = function(){ console.log("Hello, " + name + "!");}

  stub.sayWelcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
  return stub;
})();

摘要

显示模块模式与模块模式的其他变体之间的区别主要在于引用公共成员的方式。结果,RMP更加易于使用和修改,这也说明了它的流行。但是,(我认为)这些优势的代价是巨大的,Addy
Osmani在“揭示模块模式”一文中提到了这一点,

这种模式的缺点是,如果私有功能引用了公共功能,那么在需要补丁的情况下,该公共功能不能被覆盖。这是因为私有函数将继续引用私有实现,并且该模式不适用于公共成员,仅适用于函数。

引用私有变量的公共对象成员也应遵守上面的无补丁规则说明。

因此,使用“显示模块”模式创建的模块可能比使用原始“模块”模式创建的模块更脆弱,因此在使用过程中应格外小心。



 类似资料:
  • 本文向大家介绍javascript设计模式之module(模块)模式,包括了javascript设计模式之module(模块)模式的使用技巧和注意事项,需要的朋友参考一下 模块是任何强大应用程序中不可或缺的一部分,它通常能帮助我们清晰地分离和组织项目中的代码单元。 js中实现模块的方法:  1.对象字面量表示法  2.Module模式  3.AMD模块  4.CommonJS模块  5.ECMAS

  • 问题内容: 我找不到任何可访问的示例来说明如何将两个(或多个)不同的模块连接在一起一起工作。 因此,我想问一下是否有人有时间编写示例来解释模块如何协同工作。 问题答案: 为了采用模块化设计模式,您需要首先了解以下概念: 立即调用的函数表达式(IIFE): 您可以通过两种方式使用这些功能。1.函数声明2.函数表达式。 这里使用函数表达式。 什么是名称空间?现在,如果我们将名称空间添加到上面的代码中,

  • 由于我正在学习通过设计模式的概念,也希望实现支付模块在我的项目中使用适当的设计模式。为此,我创建了一些示例代码。 目前,我有两个具体的实现支付和。但具体实施将在项目上进一步补充。 支付服务 信用卡和付费朋友服务 客户端代码实现 此更新是否与策略模式内联?

  • 本文向大家介绍javascript设计模式之装饰者模式,包括了javascript设计模式之装饰者模式的使用技巧和注意事项,需要的朋友参考一下 在js函数开发中,想要为现有函数添加与现有功能无关的新功能时,按普通思路肯定是在现有函数中添加新功能的代码。这并不能说错,但因为函数中的这两块代码其实并无关联,后期维护成本会明显增大,也会造成函数臃肿。 比较好的办法就是采用装饰器模式。在保持现有函数及其内

  • 本文向大家介绍javascript设计模式之迭代器模式,包括了javascript设计模式之迭代器模式的使用技巧和注意事项,需要的朋友参考一下 迭代器模式分为内部迭代器和外部迭代器,内部迭代器就是在函数内部定义好迭代的规则,它完全接手整个迭代的过程,外部只需一次初始调用。 内部迭代器 以下自行实现的类似jquery中$.each()的each()函数就是内部迭代器 内部迭代器在调用时非常方便,但是

  • 模块 模块是任何健壮的应用程序体系结构不可或缺的一部分,特点是有助于保持应用项目的代码单元既能清晰地分离又有组织。 在JavaScript中,实现模块有几个选项,他们包括: 模块化模式 对象表示法 AMD模块 CommonJS 模块 ECMAScript Harmony 模块 我们在书中后面的现代模块化JavaScript设计模式章节中将探讨这些选项中的最后三个。 模块化模式是基于对象的文字部分,