Javascript的一种模块模式
作者:秦歌 来源:蓝色理想 发布时间:2007-12-05 14:04:00
全局变量是魔鬼。在YUI中,我们仅用两个全局变量:YAHOO和YAHOO_config。YUI的一切都是使用YAHOO对象级的成员或这个成员作用域内的变量。我们建议在你的应用程序也使用类似的规则。
Douglas Crockford已经传授了一个有用的单例模式(singleton pattern)实现此规则,我认为他的模式有益于你基于YUI的那些应用。Douglas叫它模块模式(module pattern)。它是如下工作的:
1. 创建一个命名空间对象:如果你使用YUI,可以用YAHOO.namespace()方法:
YAHOO.namespace("myProject");
这分配了一个空的myProject对象,是YAHOO的一个成员(如 果myProject已存在的话,则不会被覆盖)。现在我们可以开始添加YAHOO.myProject的成员。
2. 对你的命名空间对象分配一个匿名函数返回值:
YAHOO.myProject.myModule = function () {
return {
myPublicProperty: "我作为YAHOO.myProject.myModule.myPublicProperty被访问。";
myPublicMethod: function () {
YAHOO.log("我作为YAHOO.myProject.myModule.myPublicMethod被访问。");
}
};
}(); // 这个括号导致匿名函数被执行且返回
注意有闭合大括号和紧接着的括号()的最后一行—这种符号导致了匿名函数的立即执行,返回包含myPublicProperty和myPublicMethod的对象。只要这个匿名函数一返回,返回对象就作为YAHOO.myProject.myModule被访问。
3. 在匿名函数中,在返回语句前加入“私有”方法和变量。到目前为止,我们只是将myPublicProperty和myPublicMethod直接分配到YAHOO.myProject.myModule中。此外,当我们在返回语句之前放置一些代码时,这个模式还支持被增加的效用。
YAHOO.myProject.myModule = function () {
//“私有”变量:
var myPrivateVar = “我仅能在YAHOO.myProject.myModule内被访问。”;
//私有方法:
var myPrivateMethod = function () {
YAHOO.log(”我仅能在YAHOO.myProject.myModule内被访问。”);
}
return {
myPublicProperty: “我作为YAHOO.myProject.myModule.myPublicProperty能被访问。”
myPublicMethod: function () {
YAHOO.log(”我作为YAHOO.myProject.myModule.myPublicMethod能被访问。”);
//在myProject,我能访问私有的变量和方法
YAHOO.log(myPrivateVar);
YAHOO.log(myPrivateMethod());
//myPublicMethod的原生作用域是myProject,我们可以用“this”来访问公共成员。
YAHOO.log(this.myPublicProperty);
}
};
}();
在上面的代码中,我们从一个匿名函数返回有两个成员的一个对象。在YAHOO.myProject.myModule内部,可以分别用this.myPublicProperty和this.myPublicMethod来访问。在YAHOO.myProject.myModule外部,公共成员可以用YAHOO.myProject.myModule.myPublicProperty和YAHOO.myProject.myModule.myPublicMethod来访问。
私有变量myPrivateProperty和myPrivateMethod只能被匿名函数本身或返回对象的成员访问。尽管匿名函数会立即执行和终止,但它们依然是保留着,凭借闭包(closure)的力量——通过一个函数的局部变量在这个函数返回后是保留的规则。只要 YAHOO.myProject.myModule需要它们,我们的两个私有变量就不会被销毁。
4. 实践这个模式。让我们来看看这个模式的一个常见应用案例。假设你有一个列表,列表上的一些项可以被拖拽。应用拖拽的项上有拖拽的CSS类。
<!--这个脚本文件包含所有的YUI实用程序-->
<script type="text/javascript"
src="http://yui.yahooapis.com/2.2.2/build/utilities/
utilities.js"></script>
<ul id="myList">
<li class="draggable">一项</li>
<li>二项</li> <!--二项将不能被拖拽-->
<li class="draggable">三项</li>
</ul>
<script>
YAHOO.namespace("myProject");
YAHOO.myProject.myModule = function () {
//YUI实用程序的私有简写引用:
var yue = YAHOO.util.Event,
yud = YAHOO.util.Dom;
//私有方法
var getListItems = function () {
// 注意这个地方使用其他的私有变量,包括"yud"YAHOO.util.Dom的简写:
var elList = yud.get("myList");
var aListItems = yud.getElementsByClassName(
"draggable", //得到仅有CSS类"draggable"的项
"li", //仅返回列表项
elList //限定搜索改元素的子
);
return aListItems;
};
//这个放回的对象将变成YAHOO.myProject.myModule:
return {
aDragObjects: [], //可对外访问的,存储DD对象
init: function () {
//直到DOM完全加载好,才实现列表项可拖拽:
yue.onDOMReady(this.makeLIsDraggable, this, true);
},
makeLIsDraggable: function () {
var aListItems = getListItems(); //我们可以拖拽的那些元素
for (var i=0, j=aListItems.length; i<j; i++) {
this.aDragObjects.push(new YAHOO.util.DD(aListItems[i]));
}
}
};
}();
//上面的代码已经执行,所以我们能立即访问init方法:
YAHOO.myProject.myModule.init();
</script>
这是一个简单的例子,特意写的详细一些——如果按照这种方式做,我们无疑能把它写的更紧凑。当项目变得更加复杂和它的API增加,这个模式缩放的很好。通过这种方式,它避免了全局命名空间,提供了对外的可以访问的API方法,支持受保护或“私有”的数据和方法。
原文:《a javascript module pattern》。这是在YUI blog上的,有的地方可能打不开,可以搜一下英文的转载或者利用搜索引擎的缓存也能看。
《A JavaScript Module Pattern - JavaScript的一种模组模式》这是别人的翻译,参考了不少,不过感觉挺不方便看的,这是我翻译的这篇文章的一个原因,当然最主要的原因是这篇文章算是学习YUI的最基础的文章了,整个YUI的模块模式都基于此。
秦歌(YanKaven) 的站点:http://dancewithnet.com/
猜你喜欢
- 以下的文章主要是介绍SQL Server数据库与其实际应用元数据,我前两天在相关网站看见SQL Server数据库与其实际应用元数据的资料,
- 很常见的一个图片轮播Flash,使用之后发现在IE下按F5刷新之后Flash区域就变成一大块背景色,内容轮播出不来了。有趣的是右键点击Fla
- 1 新建类库MyTestDLL2 右击项目“MyTestDLL”-》属性-》生成-》勾选“为COM互操作注册”3 打开 AssemblyIn
- 症状: 访问asp网页的时候出现如下错误:Server object error ''ASP 0178 : 80070005
- 如果能,请问如何实现 谢谢set aa=server.cre
- 1.不装入数据库而启动事例 可以不装入数据库而启动事例,一般是在数据库才创建时才可以这样做:STARTUP NOMOUNT2.启动事例并装入
- 编写思路:把本地文件在客户端通过base64编码以后发送目的地.测试过程中,上传文件过大,导致超时不成功,后来经过改善.把编码分
- ASP中给函数传参确实是个麻烦事,当参数个数特别多的时候(比如有七八个或者更多的参数个数)差不多就要眼冒金星了,一个个的数吧。而且要命的是参
- MySQL分区方便了我们的使用,但是MySQL分区究竟能做些什么,MySQL分区有没有什么限制呢?阅读下文,您就能找到答案。MySQL分区能
- 如果没有了解栅格系统是什么,建议看完这篇文章以后再回来。其实有很种 CSS 写法实现栅格系统,很多 CSS 库也都会提供类似的栅格系统实现(
- 是因工作需要做的一个批量修改代码的小东西,拿出来与大家分享。 目前可以处理的文件类型:.asp .inc .htm .html
- 但凡设计师都对简洁的设计情有独钟,我们不喜欢复杂,却也不能不会rich。先来看下“rich”在字典里的意思:(1) having an ab
- 1) 用正式表达式 regexp "[u0391-uFFE5]"2) 用length和char_lengthdrop t
- 要做好一个HTML邮件,说简单,还真不怎么复杂,说它复杂,其实也不难。-_-!!以前写过类似的[ 关于HTML邮件的总结 ],最近又犯愁,就
- 引言 性能是一个特征。您必须预先设计性能,否则您以后就得重写应用程序。就是说,有哪些好的策略可使 Active Server Pages (
- 此文刊登在《程序员》三月期,有删改提到安全问题,首先想到应付这些问题的应该是系统管理员以及后台开发工程师们,而前端开发工程师似乎离这些问题很
- 这次我们讨论的是,区分有单选框的选项和普通的选项~~乍听起来,可能不太理解我说了什么,下面举个例子先~~1、标签的单选~~例如QQ秀的支付流
- 首先请把手放胸前成沉思状:我上了生活,还是被生活上了自己?没想出答案把,恩,可以读下文了。从语义角度讲,同一事物的不同表述可以反映人的主观视
- 在上一篇文章中 ,我说到:强硬的把CSS和HTML塞到PHP里面可以防止代码太枯燥(DRY)并最终导致代码臃肿,因为的CSS和HTML需要比
- 我们先看一下JavaScript中关系运算符的类型转换规则:关系运算符(<、>、<=、>=) 试图将 express