模块模式最初被定义为一种为传统软件工程中的类提供私有和公共封装的方法。
在使用模块模式时,我们可能会发现定义一个简单的模板来开始使用它很有用。这是一个涵盖名称间距、公共和私有变量的内容。
在 JavaScript 中,模块模式用于进一步模拟类的概念,使我们能够在单个对象中包含公共/私有方法和变量,从而将特定部分与全局范围隔离开来。这会降低我们的函数名称与页面上其他脚本中定义的其他函数发生冲突的可能性。
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();
优势
为什么模块模式是一个不错的选择?对于初学者来说,至少从 JavaScript 的角度来看,对于来自面向对象背景的开发人员来说,它比真正的封装概念要干净得多。
其次,它支持私有数据——因此,在模块模式中,我们代码的公共部分可以接触到私有部分,而外界无法接触到类的私有部分。
缺点
模块模式的缺点是,当我们以不同的方式访问公共和私有成员时,当我们希望更改可见性时,我们实际上必须对使用该成员的每个地方进行更改。
我们也不能在稍后添加到对象的方法中访问私有成员。也就是说,在许多情况下,模块模式仍然非常有用,如果使用得当,肯定有可能改善我们应用程序的结构。
显示模块模式
现在我们对模块模式有了一些了解,让我们来看一个稍微改进的版本——Christian Heilmann 的 Revealing Module 模式。
Revealing Module 模式的出现是因为 Heilmann 对当我们想要从另一个公共方法调用或访问公共变量时必须重复主对象的名称这一事实感到沮丧。他也不喜欢 Module 模式的要求对于他希望公开的内容,不得不切换到对象字面量表示法。
他努力的结果是更新了模式,我们只需在私有范围内定义所有函数和变量,并返回一个匿名对象,其中包含指向我们希望公开为私有功能的指针。
可以在下面找到如何使用显示模块模式的示例
var myRevealingModule = (function () {
var privateVar = "Ben Cherry",
publicVar = "Hey there!";
function privateFunction() {
console.log( "Name:" + privateVar );
}
function publicSetName( strName ) {
privateVar = strName;
}
function publicGetName() {
privateFunction();
}
// Reveal public pointers to
// private functions and properties
return {
setName: publicSetName,
greeting: publicVar,
getName: publicGetName
};
})();
myRevealingModule.setName( "Paul Kinlan" );
优势
这种模式使我们的脚本语法更加一致。它还在模块末尾更清楚地说明了我们的哪些函数和变量可以公开访问,从而简化了可读性。
缺点
这种模式的一个缺点是,如果私有函数引用公共函数,那么如果需要补丁,则该公共函数不能被覆盖。这是因为私有函数将继续引用私有实现,并且该模式不适用于公共成员,仅适用于函数。
引用私有变量的公共对象成员也受上述无补丁规则注释的约束。