Javascript Module Pattern有什么好处

What is the benefit of the Javascript Module Pattern?

本文关键字:什么 Module Pattern Javascript      更新时间:2023-09-26

我一直在做研究,为我的团队提出一种标准化的Javascript编码风格。 大多数资源现在建议使用涉及闭包的"模块"模式,例如:

var Module = function() { 
    someMethod = function() { /* ... */ };
    return { 
        someMethod: someMethod
    };
}();

并像Module.someMethod();一样调用它. 这种方法似乎只适用于传统 OOP 上下文中静态的方法,例如用于获取/保存数据的存储库类、用于发出外部请求的服务层等。 除非我错过了什么,否则模块模式不适用于通常需要与服务方法传递到 UI 粘附代码的数据类(想想 DTO(一起使用。

我看到引用的一个常见好处是,您可以使用模块模式在 Javascript 中拥有真正的私有方法和字段,但这也可以与能够使用类似于以下内容的"经典"Javascript 样式的静态实例方法一起实现:

myClass = function(param) { 
    // this is completely public
    this.publicProperty = 'Foo';
    // this is completely private
    var privateProp = param;
    // this function can access the private fields
    // AND can be called publicly; best of both?
    this.someMethod = function() { 
        return privateProp;
    };
    // this function is private.  FOR INTERNAL USE ONLY
    function privateMethod() { 
        /* ... */
    };
}
// this method is static and doesn't require an instance
myClass.staticMethod = function() { /* ... */ };
// this method requires an instance and is the "public API"
myClass.prototype.instanceMethod = function() { /* ... */ };

所以我想我的问题是是什么让模块模式比传统风格更好? 它更干净一些,但这似乎是唯一立即明显的好处;事实上,传统风格似乎提供了提供真实封装的能力(类似于真正的 OOP 语言,如 Java 或 C#(,而不是简单地返回仅静态方法的集合。

我错过了什么吗?

模块模式可用于创建原型,请参阅:

var Module = function() { 
  function Module() {};
  Module.prototype.whatever = function() {};
  return Module
}();
var m = new Module();
m.whatever();

正如另一张海报所说,干净的全局命名空间是它的原因。然而,实现此目的的另一种方法是使用 AMD 模式,该模式还可以解决依赖关系管理等其他问题。它还将所有内容包装在各种闭合中。这是对AMD的一个很好的介绍,它代表异步模块定义。

我还建议阅读JavaScript模式,因为它彻底涵盖了各种模块模式的原因。

上面的模块模式毫无意义。您所做的只是使用一个闭包来返回带有原型的构造函数。您可以通过以下方式实现相同的目标:

function Module() {};
Module.prototype.whatever = function() {};
var m = new Module();
m.whatever();

实际上,您将保存一个对象(闭包(免于创建,具有相同的输出。

我对模块模式的另一个问题是,如果您将其用于私有封装,则只能轻松地将其用于单例而不是具体类。要使用私有数据创建具体类,您最终会包装两个关闭器,这变得很丑陋。我也同意,当下划线伪私有属性可见时,能够调试它们要容易得多。"如果有人错误地使用你的类怎么办"的整个概念从来都是没有道理的。制作一个干净的公共API,记录它,如果人们没有正确遵循它,那么你的团队中有一个糟糕的程序员。在Javascript中隐藏变量(可以在Firefox中使用eval发现(所需的工作量不值得使用JS,即使对于大中型项目也是如此。人们不会窥探你的对象来学习它们,他们会阅读你的文档。如果你的文档很好(例如使用JSDoc(,那么他们会坚持下去,就像我们使用我们需要的每个第三方库一样。我们不会"篡改"jQuery或YUI,我们只是信任和使用公共API,而不太关心它如何在下面使用或使用什么。

你忘了提到模块模式的另一个好处是,它促进了全局命名空间中的混乱,即人们在说"不要污染全局命名空间"时所指的。当然,您可以在经典方法中做到这一点,但似乎在匿名函数之外创建对象会更容易在全局命名空间中创建这些对象。

换句话说,模块模式促进了自包含代码。模块通常会将一个对象推送到全局命名空间,与模块的所有交互都通过此对象。这就像一个"主要"方法。

减少全局命名空间中的混乱是好的,因为它减少了与其他框架和 JavaScript 代码发生冲突的机会。