Javascript模块模式有什么好处?
我一直在研究为我的团队提供标准化的JavaScript编码风格。 大多数资源现在推荐涉及闭包的“模块”模式,例如:
var Module = function() {
someMethod = function() { /* ... */ };
return {
someMethod: someMethod
};
}();
并像Module.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#),而不是简单地返回一组静态方法。
有什么我失踪?
上面的模块模式是毫无意义的。 你所做的只是使用一个闭包来返回一个带有原型的构造函数。 你可能已经达到了与
function Module() {};
Module.prototype.whatever = function() {};
var m = new Module();
m.whatever();
事实上,你将会保存一个对象(闭包)被创建,具有相同的输出。
如果你使用它来进行私有封装,那么我的另一个带有模块模式的牛肉就是它,你只能用singletons而不是具体的类来使用它。 要创建具有私人数据的具体类,最终要封装两个闭合器,这会变得很难看。 我也同意,当它们可见时,能够调试下划线伪私有属性会更容易。 “如果某人错误地使用你的班级怎么办”这个概念是没有道理的。 制作一个干净的公共API,记录它,如果人们没有正确地遵循它,那么你的团队中就有一个糟糕的程序员。 Javascript中隐藏变量所需的工作量(在Firefox中可通过eval进行发现)不值得使用JS,即使对于大中型项目也是如此。 人们不会窥探你的物品来学习它们,他们会阅读你的文档。 如果你的文档很好(例如使用JSDoc),那么他们会坚持下去,就像我们使用我们需要的每个第三方库。 我们不会“篡改”jQuery或YUI,我们只是相信并使用公共API,而不会过多地关注它在底层使用的方式或用途。
忘记提及模块模式的另一个好处是,它在全局名称空间中促进了更少的混乱,也就是当人们说“不污染全局名称空间”时引用的内容。 当然,你可以用传统的方法来做到这一点,但似乎在匿名函数之外创建对象会更容易在全局名称空间中创建这些对象。
换句话说,模块模式可以促进自包含的代码。 模块通常会将一个对象推送到全局名称空间,并且与模块的所有交互都会通过该对象。 这就像一个“主要”方法。
在全局名称空间中减少混乱是很好的,因为它减少了与其他框架和JavaScript代码发生冲突的机会。
模块模式也可用于创建原型,请参阅:
var Module = function() {
function Module() {};
Module.prototype.whatever = function() {};
return Module
}();
var m = new Module();
m.whatever();
另一个海报称干净的全局命名空间是其原因。 然而,实现这一目标的另一种方法是使用AMD模式,它也解决了其他问题,如依赖管理。 它还将所有内容都封闭在一起。 这里有一个很好的AMD介绍,代表异步模块定义。
我还建议阅读JavaScript模式,因为它完全涵盖了各种模块模式的原因。
链接地址: http://www.djcxy.com/p/59463.html