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 相关文章推荐
面向对象的编程思想在javascript中的运用上部
Nov 20 Javascript
提示$ is not defined错误分析及解决
Apr 09 Javascript
JQ获取动态加载的图片大小的正确方法分享
Nov 08 Javascript
php利用curl获取远程图片实现方法
Oct 26 Javascript
JS实现Select的option上下移动的方法
Mar 01 Javascript
jQuery代码实现图片墙自动+手动淡入淡出切换效果
May 09 Javascript
js实现适配不同的屏幕大小
Apr 10 Javascript
js 概率计算(简单版)
Sep 12 Javascript
Vue的elementUI实现自定义主题方法
Feb 23 Javascript
VUE中v-on:click事件中获取当前dom元素的代码
Aug 22 Javascript
layui 阻止图片上传的实例(before方法)
Sep 26 Javascript
解决vue请求接口第一次成功,第二次失败问题
Sep 08 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脚本使WordPress的主题支持Widget侧边栏
2015/12/14 PHP
javascript面向对象之Javascript 继承
2010/05/04 Javascript
JSON JQUERY模板实现说明
2010/07/03 Javascript
基于jQuery的判断iPad、iPhone、Android是横屏还是竖屏的代码
2014/05/11 Javascript
js文件包含的几种方式介绍
2014/09/28 Javascript
javascript常用的方法整理
2015/08/20 Javascript
Bootstrap~多级导航(级联导航)的实现效果【附代码】
2016/03/08 Javascript
50 个 jQuery 插件可将你的网站带到另外一个高度
2016/04/26 Javascript
浅析JavaScript中的对象类型Object
2016/05/26 Javascript
JS控制层作圆周运动的方法
2016/06/20 Javascript
JS使用onerror捕获异常示例
2016/08/03 Javascript
nodejs连接mongodb数据库实现增删改查
2016/12/01 NodeJs
从零开始最小实现react服务器渲染详解
2018/01/26 Javascript
npm全局模块卸载及默认安装目录修改方法
2018/05/15 Javascript
vue组件开发props验证的实现
2019/02/12 Javascript
Vue组件内部实现一个双向数据绑定的实例代码
2019/04/04 Javascript
vue input标签通用指令校验的实现
2019/11/05 Javascript
Nuxt的动态路由和参数校验操作
2020/11/09 Javascript
记录一次websocket封装的过程
2020/11/23 Javascript
[06:13]DOTA2进化论(修改版)
2013/10/08 DOTA
[01:51]2014DOTA2西雅图邀请赛 MVP 外卡赛black场间采访
2014/07/09 DOTA
[55:03]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第二场 11.20
2020/11/20 DOTA
python 2.7.14安装图文教程
2018/04/08 Python
python 通过 socket 发送文件的实例代码
2018/08/14 Python
python 自动重连wifi windows的方法
2018/12/18 Python
解决python中使用PYQT时中文乱码问题
2019/06/17 Python
Python实现名片管理系统
2020/02/14 Python
Python object类中的特殊方法代码讲解
2020/03/06 Python
详解selenium + chromedriver 被反爬的解决方法
2020/10/28 Python
css3实现背景模糊的三种方式(小结)
2020/05/15 HTML / CSS
Expedia泰国:预订机票、酒店和旅游包(航班+酒店)
2016/09/27 全球购物
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2012/04/17 面试题
销售助理岗位职责
2014/02/21 职场文书
机电专业毕业生自我鉴定2014
2014/10/04 职场文书
MySQL表字段时间设置默认值
2021/05/13 MySQL
python读取mnist数据集方法案例详解
2021/09/04 Python