原文出处:http://yuiblog.com/blog/2007/06/12/module-pattern/
翻译:Frank
全局变量是一种祸害。在YUI中,我们只使用两个全局变量YAHOO和YAHOO_config。所有YUI的对象都从YAHOO这个对象层次上访问成员或属于这个成员的变量。我们建议你在您的程序中亦效仿此实践。
Douglas Crockford已经对我们传授了使用单例的模式(singletion pattern)来实现此模式,而且我认为应用到该模式来构建基于YUI,不乏一些有意思的地方。Douglas称这个为“”,看看他怎么做的?
上面的代码中,我们从一匿名函数返回一个包含两个成员的对象。在YAHOO.myProject.myModule内可分别用this.myPublicProperty和this.myPublivMethod来访问。在YAHOO.myProject.myModule外部,这些公告成员可用YAHOO.myProject.myModule.myPublicProperty 和 YAHOO.myProject.myModule.myPublicMethod访问。
翻译:Frank
全局变量是一种祸害。在YUI中,我们只使用两个全局变量YAHOO和YAHOO_config。所有YUI的对象都从YAHOO这个对象层次上访问成员或属于这个成员的变量。我们建议你在您的程序中亦效仿此实践。
Douglas Crockford已经对我们传授了使用单例的模式(singletion pattern)来实现此模式,而且我认为应用到该模式来构建基于YUI,不乏一些有意思的地方。Douglas称这个为“”,看看他怎么做的?
1、创建命名空间对象:如果你使用的YUI,你可以采用的YAHOO.namespace()的方法:
js 代码
- YAHOO.namespace("myProject");
这分配了一个空的myProject对象,是YAHOO的一个成员(但不会覆盖myProject如果已存在的话)。现在我们可以开始加入YAHOO.myProject成员。
2、从一个匿名函数返回值,分配到命名空间对象上
js 代码
- YAHOO.myProject.myModule = function () {
- return {
- myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty.";
- myPublicMethod: function () {
- YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
- }
- };
- }(); //这里括号的作用的是 执行该匿名函数并返回
注意花括号结尾的最底行,后面紧跟着一对括号() --这符号的含意是立即执行该匿名函数,返回一个包含myPublicProperty和myPublicMethod的对象。只要匿名函数能够返回,返回的那个对象便可 以YAHOO.myProject.myModule访问。
3、在匿名函数中优先加入”私有“的方法和变量(在return之前)。
到现在,我们做的只是将myPubilcProperty和myPublicMethod直接分配到YAHOO.myProject.myModule。除此之外,该模式还允许我们在return语之前执行一些代码:
私有变量如myPrivateProperty和myPrivateMethod的,只能被匿名函数本身,或是返回对象的成员访问。尽管匿名函数会立即执行和终结,但它们依然是保留着,凭借闭包(closure)的力量,只要 YAHOO.myProject.myModule需要它们,我们的两个所以变量就不会被销毁。
4、实践该模式我们来看看module pattern的实际应用。假设你有一段列表,列表的上的某些item是可被拖动的。拖动的item有一个draggable的CSS Class。
xml 代码
- <!--This script file includes all of the YUI utilities:-->
- <script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/utilities/utilities.js"></script>
- <ul id="myList">
- <li class="draggable">Item one.</li>
- <li>Item two.</li> <!--item two won't be draggable-->
- <li class="draggable">Item three.</li>
- </ul>
- <script>
- YAHOO.namespace("myProject");
- YAHOO.myProject.myModule = function () {
- //引用YUI utilities的简写:
- var yue = YAHOO.util.Event,
- yud = YAHOO.util.Dom;
- //私有方法
- var getListItems = function () {
- //注意我们使用其它的私有变量,包括 "yud"的简写
- var elList = yud.get("myList");
- var aListItems = yud.getElementsByClassName(
- "draggable", //获取只带有”draggable“CSS类的item
- "li", //只返回列表item
- elList //限制搜索该元素的children
- );
- return aListItems;
- };
- //返回的对象变为YAHOO.myProject.myModule:
- return {
- aDragObjects: [], //保存 DD objects,可对外访问
- init: function () {
- //等到DOM完全加载好,才开始创建列表item:
- 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的方法公共的访问,支持保护(protected)或”私有“的数据。
js 代码
- YAHOO.myProject.myModule = function () {
- //“私有变量”:
- var myPrivateVar = "I can be accessed only from within YAHOO.myProject.myModule.";
- //“私有方法”:
- var myPrivateMethod = function () {
- YAHOO.log("I can be accessed only from within YAHOO.myProject.myModule");
- }
- return {
- myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty."
- myPublicMethod: function () {
- YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
- //Within myProject, I can access "private" vars and methods:
- YAHOO.log(myPrivateVar);
- YAHOO.log(myPrivateMethod());
- //The native scope of myPublicMethod is myProject; we can
- //access public members using "this":
- YAHOO.log(this.myPublicProperty);
- }
- };
- }(); //这里括号的作用的是 执行该匿名函数并返回
上面的代码中,我们从一匿名函数返回一个包含两个成员的对象。在YAHOO.myProject.myModule内可分别用this.myPublicProperty和this.myPublivMethod来访问。在YAHOO.myProject.myModule外部,这些公告成员可用YAHOO.myProject.myModule.myPublicProperty 和 YAHOO.myProject.myModule.myPublicMethod访问。