Javascript的一种模块模式


Posted in Javascript onMarch 22, 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 相关文章推荐
在Z-Blog中运行代码[html][/html](纯JS版)
Mar 25 Javascript
jquery实现商品拖动选择效果代码(自写)
May 28 Javascript
js分页代码分享
Apr 28 Javascript
JavaScript常用的弹出广告及背投广告实现方法
Feb 06 Javascript
javascript实时显示当天日期的方法
May 20 Javascript
跟我学习javascript的闭包
Nov 16 Javascript
JQuery点击行tr实现checkBox选中的简单实例
May 26 Javascript
浅谈js中的引用和复制(传值和传址)
Sep 18 Javascript
AngularJS中重新加载当前路由页面的方法
Mar 09 Javascript
利用Electron简单撸一个Markdown编辑器的方法
Jun 10 Javascript
微信小程序动态评分展示/五角星展示/半颗星展示/自定义长度展示功能的实现
Jul 22 Javascript
js实现跳一跳小游戏
Jul 31 Javascript
javascript cookie解码函数(兼容ff)
Mar 17 #Javascript
简单的JS多重继承示例
Mar 13 #Javascript
JMenuTab简单使用说明
Mar 13 #Javascript
JObj预览一个JS的框架
Mar 13 #Javascript
DHTML Slide Show script图片轮换
Mar 03 #Javascript
JavaScript面向对象编程
Mar 02 #Javascript
一个javascript参数的小问题
Mar 02 #Javascript
You might like
PHP实现的封装验证码类详解
2013/06/18 PHP
php中将一段数据存到一个txt文件中并显示其内容
2014/08/15 PHP
[原创]IE view-source 无法查看看源码 JavaScript看网页源码
2009/07/19 Javascript
input禁止键盘及中文输入,但可以点击
2014/02/13 Javascript
Jquery简单分页实现方法
2015/07/24 Javascript
jquery不常用方法汇总
2015/07/26 Javascript
JavaScript中的Array 对象(数组对象)
2016/06/02 Javascript
js与applet相互调用的方法
2016/06/22 Javascript
js数字计算 误差问题的快速解决方法
2017/02/28 Javascript
Node.js查找当前目录下文件夹实例代码
2017/03/07 Javascript
详解如何实现一个简单的Node.js脚手架
2017/12/04 Javascript
解决vue router组件状态刷新消失的问题
2018/08/01 Javascript
js纯前端实现腾讯cos文件上传功能的示例代码
2019/05/14 Javascript
vue自定义表单生成器form-create使用详解
2019/07/19 Javascript
vue封装可复用组件confirm,并绑定在vue原型上的示例
2019/10/31 Javascript
vue使用better-scroll实现滑动以及左右联动
2020/06/30 Javascript
动态实现element ui的el-table某列数据不同样式的示例
2021/01/22 Javascript
[05:46]2018完美盛典-《同梦共竞》
2018/12/17 DOTA
Python读取一个目录下所有目录和文件的方法
2016/07/15 Python
python实现可以断点续传和并发的ftp程序
2016/09/13 Python
Python3之简单搭建自带服务器的实例讲解
2018/06/04 Python
使用pandas将numpy中的数组数据保存到csv文件的方法
2018/06/14 Python
python实现字符串中字符分类及个数统计
2018/09/28 Python
PyTorch的深度学习入门之PyTorch安装和配置
2019/06/27 Python
Django单元测试中Fixtures用法详解
2020/02/25 Python
Python 批量读取文件中指定字符的实现
2020/03/06 Python
基于jupyter代码无法在pycharm中运行的解决方法
2020/04/21 Python
Keras 快速解决OOM超内存的问题
2020/06/11 Python
如何利用python正则表达式匹配版本信息
2020/12/09 Python
举例详解CSS3中的Transition
2015/07/15 HTML / CSS
最畅销的视频游戏享受高达90%的折扣:CDKeys
2020/02/10 全球购物
电脑教师的教学自我评价
2013/11/26 职场文书
企业诚信承诺书
2014/05/23 职场文书
2015教师节师德演讲稿
2015/03/19 职场文书
会议通知
2015/04/15 职场文书
MySQL实战记录之如何快速定位慢SQL
2022/03/23 MySQL