Javascript的一种模块模式


Posted in Javascript onSeptember 08, 2010

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方法,支持受保护或“私有”的数据和方法。
  • [1]原文:《a javascript module pattern》。这是在YUI blog上的,有的地方可能打不开,可以搜一下英文的转载或者利用搜索引擎的缓存也能看。
  • [2]《A JavaScript Module Pattern ? JavaScript的一种模组模式》这是别人的翻译,参考了不少,不过感觉挺不方便看的,这是我翻译的这篇文章的一个原因,当然最主要的原因是这篇文章算是学习YUI的最基础的文章了,整个YUI的模块模式都基于此。
原文地址:http://dancewithnet.com/2007/12/04/a-javascript-module-pattern/
Javascript 相关文章推荐
javascript function、指针及内置对象
Feb 19 Javascript
Jquery Ajax学习实例7 Ajax所有过程事件分析示例
Mar 23 Javascript
jquery(live)中File input的change方法只起一次作用的解决办法
Oct 21 Javascript
jQuery操作 input type=checkbox的实现代码
Jun 14 Javascript
javascript新建标签,判断键盘输入,以及判断焦点(示例代码)
Nov 25 Javascript
jQuery点缩略图弹出层显示大图片
Feb 13 Javascript
js提示框替代系统alert,自动关闭alert对话框的实现方法
Nov 07 Javascript
在javaScript中检测数据类型的几种方式小结
Mar 04 Javascript
angularjs路由传值$routeParams详解
Sep 05 Javascript
浅谈Vue初学之props的驼峰命名
Jul 19 Javascript
JS高阶函数原理与用法实例分析
Jan 15 Javascript
JS addEventListener()和attachEvent()方法实现注册事件
Jan 11 Javascript
jQeury淡入淡出需要注意的问题
Sep 08 #Javascript
jQuery之浮动窗口实现代码(两种方法)
Sep 08 #Javascript
Jquery ThickBox插件使用心得(不建议使用)
Sep 08 #Javascript
jquery的Tooltip插件 qtip使用详细说明
Sep 08 #Javascript
jquery的Theme和Theme Switcher使用小结
Sep 08 #Javascript
复制小说文本时出现的随机乱码的去除方法
Sep 07 #Javascript
extjs grid设置某列背景颜色和字体颜色的实现方法
Sep 06 #Javascript
You might like
非常好的php目录导航文件代码
2006/10/09 PHP
自己前几天写的无限分类类
2007/02/14 PHP
php图片验证码代码
2008/03/27 PHP
PHP通过调用新浪API生成t.cn格式短网址链接的方法详解
2019/02/20 PHP
jquery实现简单易懂的图片展示小例子
2013/11/21 Javascript
node.js中的fs.writeFile方法使用说明
2014/12/14 Javascript
js带前后翻页的图片切换效果代码分享
2015/09/08 Javascript
跟我学习javascript的最新标准ES6
2015/11/20 Javascript
JS实现的自定义显示加载等待图片插件(loading.gif)
2016/06/17 Javascript
使用 NodeJS+Express 开发服务端的简单介绍
2017/04/07 NodeJs
nodejs利用ajax实现网页无刷新上传图片实例代码
2017/06/06 NodeJs
详解react使用react-bootstrap当轮子造车
2017/08/15 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
2019/05/07 Javascript
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
2019/09/19 Javascript
JavaScript RegExp 对象用法详解
2019/09/24 Javascript
layui时间控件选择时间范围的实现方法
2019/09/28 Javascript
python封装对象实现时间效果
2020/04/23 Python
python 字典(dict)遍历的四种方法性能测试报告
2014/06/25 Python
尝试用最短的Python代码来实现服务器和代理服务器
2016/06/23 Python
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
简单谈谈Python中的json与pickle
2017/07/19 Python
python批量赋值操作实例
2018/10/22 Python
python暴力解压rar加密文件过程详解
2019/07/05 Python
python单线程下实现多个socket并发过程详解
2019/07/27 Python
python 爬虫如何实现百度翻译
2020/11/16 Python
matplotlib对象拾取事件处理的实现
2021/01/14 Python
Swisse官方海外旗舰店:澳大利亚销量领先,自然健康品牌
2017/12/15 全球购物
日本乐天德国站:Rakuten.de
2019/05/16 全球购物
迪奥美国官网:Dior美国
2019/12/07 全球购物
Myprotein西班牙官网:欧洲第一大运动营养品牌
2020/02/24 全球购物
新锐科技Java程序员面试题
2016/07/25 面试题
公司会计主管岗位责任制
2014/03/01 职场文书
优质服务活动实施方案
2014/05/02 职场文书
2016年七夕爱情寄语
2015/12/04 职场文书
Python数据可视化之Seaborn的安装及使用
2022/04/19 Python
使用Redis实现分布式锁的方法
2022/06/16 Redis