Javascript模块模式分析


Posted in Javascript onMay 16, 2008

Douglas Crockford已经传授了一个有用的单例模式(singleton pattern)实现此规则,我认为他的模式有益于你基于YUI的那些应用。Douglas叫它模块模式(module pattern)。它是如下工作的:

创建一个命名空间对象:如果你使用YUI,可以用YAHOO.namespace()方法: YAHOO.namespace("myProject");这分配了一个空的myProject对象,是YAHOO的一个成员(如 果myProject已存在的话,则不会被覆盖)。现在我们可以开始添加YAHOO.myProject的成员。 
对你的命名空间对象分配一个匿名函数返回值: 
YAHOO.myProject.myModule = function () {
return  {
  myPublicProperty: "我作为YAHOO.myProject.myModule.myPublicProperty被访问。";
  myPublicMethod: function () {
    YAHOO.log("我作为YAHOO.myProject.myModule.myPublicMethod被访问。");
  }
};
}(); // 这个括号导致匿名函数被执行且返回

注意有闭合大括号和紧接着的括号()的最后一行—这种符号导致了匿名函数的立即执行,返回包含myPublicProperty和myPublicMethod的对象。只要这个匿名函数一返回,返回对象就作为YAHOO.myProject.myModule被访问。 

在匿名函数中,在返回语句前加入“私有”方法和变量。到目前为止,我们只是将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需要它们,我们的两个私有变量就不会被销毁。 

实践这个模式。让我们来看看这个模式的一个常见应用案例。假设你有一个列表,列表上的一些项可以被拖拽。应用拖拽的项上有拖拽的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的模块模式都基于此。 

Javascript 相关文章推荐
jQuery 动态酷效果实现总结
Dec 27 Javascript
jquery中dom操作和事件的实例学习 仿yahoo邮箱登录框的提示效果
Nov 30 Javascript
含有CKEditor的表单如何提交
Jan 09 Javascript
JS返回iframe中frameBorder属性值的方法
Apr 01 Javascript
JavaScript动态添加事件之事件委托
Jul 12 Javascript
vue.js入门(3)——详解组件通信
Dec 02 Javascript
JS复制对应id的内容到粘贴板(Ctrl+C效果)
Jan 23 Javascript
JS按条件 serialize() 对应标签的使用方法
Jul 24 Javascript
解决Angular.js中使用Swiper插件不能滑动的问题
Feb 26 Javascript
在vue中使用vant TreeSelect分类选择组件操作
Nov 02 Javascript
vue3.0+vue-router+element-plus初实践
Dec 02 Vue.js
原生js实现自定义滚动条组件
Jan 20 Javascript
Dom加载让图片加载完再执行的脚本代码
May 15 #Javascript
直接生成打开窗口代码,不必下载
May 14 #Javascript
地震发生中逃生十大法则
May 12 #Javascript
通过修改referer下载文件的方法
May 11 #Javascript
JS启动应用程序的一个简单例子
May 11 #Javascript
一段利用WSH获取登录时间的jscript代码
May 11 #Javascript
一段利用WSH修改和查看IP配置的代码
May 11 #Javascript
You might like
用PHP制作静态网站的模板框架(二)
2006/10/09 PHP
PHP生成指定长度随机数最简洁的方法
2014/07/14 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
ThinkPHP5+UEditor图片上传到阿里云对象存储OSS功能示例
2019/08/05 PHP
jQuery总体架构的理解分析
2011/03/07 Javascript
用javascript作一个通用向导说明
2011/08/30 Javascript
jquery.ui.draggable中文文档(原文翻译)
2013/11/15 Javascript
jquery实现可拖拽弹出层特效
2015/01/04 Javascript
JS获取图片高度宽度的方法分享
2015/04/17 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
2016/01/13 Javascript
浅谈jQuery中ajaxPrefilter的应用
2016/08/01 Javascript
seajs中最常用的7个功能、配置示例
2017/10/10 Javascript
微信开发之企业付款到银行卡接口开发的示例代码
2018/09/18 Javascript
vue-cli 3.0 自定义vue.config.js文件,多页构建的方法
2018/09/19 Javascript
在vue中根据光标的显示与消失实现下拉列表
2019/09/29 Javascript
如何在postman测试用例中实现断言过程解析
2020/07/09 Javascript
[03:09]DOTA2亚洲邀请赛 LGD战队出场宣传片
2015/02/07 DOTA
Python程序中设置HTTP代理
2016/11/06 Python
Python实现快速计算词频功能示例
2018/06/25 Python
python生成每日报表数据(Excel)并邮件发送的实例
2019/02/03 Python
Python虚拟环境库virtualenvwrapper安装及使用
2020/06/17 Python
sklearn和keras的数据切分与交叉验证的实例详解
2020/06/19 Python
CSS3中background-clip和background-origin的区别示例介绍
2014/03/10 HTML / CSS
CSS实现进度条和订单进度条的示例
2020/11/05 HTML / CSS
canvas实现俄罗斯方块的方法示例
2018/12/13 HTML / CSS
美国在线珠宝商店:SZUL
2017/02/11 全球购物
新西兰廉价汽车租赁:Snap Rentals
2018/09/14 全球购物
意大利在线药房:shop-farmacia.it
2019/03/12 全球购物
毕业自荐信
2013/12/16 职场文书
户籍证明模板
2014/09/28 职场文书
体育个人工作总结
2015/02/09 职场文书
亮剑观后感600字
2015/06/05 职场文书
2019西餐厅创业计划书范文!
2019/07/12 职场文书
30岁前绝不能错过的10本书
2019/08/08 职场文书
基于Java的MathML转图片的方法(示例代码)
2021/06/23 Java/Android
JS数组去重详情
2021/11/07 Javascript