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 相关文章推荐
如何使用jQuery Draggable和Droppable实现拖拽功能
Jul 05 Javascript
JavaScript实现存储HTML字符串示例
Apr 21 Javascript
原生js页面滚动延迟加载图片
Dec 20 Javascript
jquery悬浮提示框完整实例
Jan 13 Javascript
vue基于Vue2.0和高德地图的地图组件实例
Apr 28 Javascript
JS 学习总结之正则表达式的懒惰性和贪婪性
Jul 03 Javascript
Node.js readline 逐行读取、写入文件内容的示例
Mar 01 Javascript
vue.js编译时给生成的文件增加版本号
Sep 17 Javascript
vue计算属性computed的使用方法示例
Mar 13 Javascript
js实现随机数小游戏
Jun 28 Javascript
优化Vue中date format的性能详解
Jan 13 Javascript
vue如何使用rem适配
Feb 06 Vue.js
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中explode与split的区别介绍
2012/10/03 PHP
php绘制一条直线的方法
2015/01/24 PHP
php远程下载类分享
2016/04/13 PHP
微信公众号开发之获取位置信息php代码
2018/06/13 PHP
js中的window.open返回object的错误的解决方法
2009/08/15 Javascript
javascript 匿名函数的理解(透彻版)
2010/01/28 Javascript
javascript 验证日期的函数
2010/03/18 Javascript
zeroclipboard复制到剪切板的flash
2010/08/04 Javascript
JavaScript中的isXX系列是否继续使用的分析
2011/04/16 Javascript
关于javascript中的typeof和instanceof介绍
2012/12/04 Javascript
提取字符串中年月日的函数代码
2013/11/05 Javascript
js点击button按钮跳转到另一个新页面
2014/10/10 Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
2016/01/19 Javascript
从零开始学习Node.js系列教程之设置HTTP头的方法示例
2017/04/13 Javascript
Spring shiro + bootstrap + jquery.validate 实现登录、注册功能
2017/06/02 jQuery
Vue2.0 slot分发内容与props验证的方法
2017/12/12 Javascript
vue中改变选中当前项的显示隐藏或者状态的实现方法
2018/02/08 Javascript
Angular4 ElementRef的应用
2018/02/26 Javascript
vue实现点击展开点击收起效果
2018/04/27 Javascript
深入浅析Node.js 事件循环、定时器和process.nextTick()
2018/10/22 Javascript
小程序如何使用分包加载的实现方法
2019/05/22 Javascript
JavaScript逻辑运算符相关总结
2020/09/04 Javascript
17个Python小技巧分享
2015/01/23 Python
python抓取网页中图片并保存到本地
2015/12/01 Python
PyCharm代码整体缩进,反向缩进的方法
2018/06/25 Python
用python一行代码得到数组中某个元素的个数方法
2019/01/28 Python
深入浅析Python 命令行模块 Click
2020/03/11 Python
利用CSS3实现单选框动画特效示例代码
2016/09/26 HTML / CSS
css3中flex布局宽度不生效的解决
2020/12/09 HTML / CSS
趣天网日本站:Qoo10 JP
2019/09/18 全球购物
宏碁西班牙官网:Acer西班牙
2021/01/08 全球购物
企业后勤岗位职责
2014/02/28 职场文书
群众路线个人剖析材料及整改措施
2014/11/04 职场文书
2015新年联欢晚会开场白
2014/12/14 职场文书
2014年变电站工作总结
2014/12/19 职场文书
社区服务活动报告
2015/02/05 职场文书