如何在JavaScript中使用Revealing模块模式
我偶然发现了这个post: JavaScript的揭示模块模式 。 我想在我的项目中使用这个。
让我们想象我有一个函数abc
,我在我的主JavaScript文件中调用该函数。
这种模式是否使事情有所不同? 任何人都可以给我看一个这种模式的基本例子吗?
一个小例子:
var revealed = function(){ var a = [1,2,3]; function abc(){ return (a[0]*a[1])+a[2]; } return { name: 'revealed', abcfn: abc } }();
在启动的匿名函数中revealed
了一个值, a
和abc
对于该函数是私有的。 函数返回的是具有name
属性和abcfn
属性的对象字面值,它是对abc function
的引用。 abc function
使用私有variablesa
。 这一切都可以通过使用闭包完成 (一个函数范围内的所有东西都可以被同一个函数中的其他东西引用)。
显示使用情况:
alert(revealed.name); //=> 'revealed' alert(revealed.abcfn()); //=> 5 (1*2+3)
DC =道格拉斯·克罗克福德
RMP =揭示模块模式
DC和RMP之间的区别主要是组织/可读
例子在文章本身介绍? 你究竟在问什么,因为这些东西与文件没有任何关系,而是closures。
你把所有东西都放在一个闭包(函数)中,只显示那些你希望可以访问的部分。 DC风格和RMP的区别在于,第一个函数是在不同的地方定义的,而在RMP中它们总是在同一个地方定义,然后在公共对象文本中显示出来 。
所以在DC和RMP你有:
- 封闭使得可以定义私有部分(variables和函数)
- 私人部分
- 定义公开可见的function和variables(状态)的公共结果
这两种模式仅在可读性方面有所不同。 在DC情况下,你不能总是知道在哪里定义某些function,但是在RMP中你总是知道所有的东西都在私人部分。
在初学者的基本JavaScriptdevise模式文章中,揭示模块模式是相当不错的。
由作者“道格拉斯·克罗克福德创造物体的模式”所调用的方法实际上是由Richard Cornford 等人主要开发的模块模式。 请参阅http://groups.google.com/group/comp.lang.javascript/msg/9f58bd11bd67d937
举例来说,有很多。 阅读下面的文章,并遵循一些链接: http : //peter.michaux.ca/articles/module-pattern-provides-no-privacy-at-least-not-in-javascript-tm
我喜欢使用揭示模块模式与单例模式的混合,以便我可以保持结构化代码与模块模式的好处:
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();
我在博客上写了更多关于这方面的信息:
http://curtistimson.co.uk/js/mixing-revealing-module-and-singleton-javascript-patterns/
对于模块外部的代码,它没有什么区别。 在那篇文章中的所有3个案例中,这些方法都是以相同的方式来调用的。 但是模块本身的结构在内部是不同的。
Crockford的模块模式和他们所说的“揭示模块模式”在结构上几乎是一回事。 唯一的区别是,他们将方法分配给本地var首先是为了更可读。 但实际上并没有什么特别之处,在你的链接中你有一些例子。
揭示模块的基本概念是你有一个封装了它的数据和行为的Object
:
var Module = (function(){ var privateStuff = {}; var publicStuff = {}; return publicStuff; })();
但是,在使用这种模式时,应该使用一些最佳实践。 这里有一个模块(“ Modulus
”),其中有一些属性用于演示,它采用了以下一些实践:
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 }; })());
注意(new (function SomeClass(){ ... })());
句法。 像这样使用new
可以让你在closures中使用this
关键字。 如果您需要inheritance其他类的属性( AbstractSomeClass.call(this, 998);
),那么这很方便AbstractSomeClass.call(this, 998);
但是,您仍然需要揭示您想公开的属性,例如:
return { id: this.id, name: this.name };
另外请注意,我们将this
赋值为 – 这允许我们使用Parent- this
,它具有它自己的this
作用域( this.value = thus.name || name;
)
再一次,这些只是build议的一些公约和最佳实践。
这里是显示模块模式的小例子。
它提供了一个像类一样声明私有和公共函数的工具。这是这种模式的主要优点。如果我们不想公开某些可以从全局访问的function,是如何使私人和公共职能的例子。还有一件事情是一个可自行执行的代码块。
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()将不可访问,因为它在私人范围内。 我们只能访问返回对象中声明的那些函数,因为它是公共函数表示