秦歌(YanKaven) 的站點(diǎn):http://dancewithnet.com/
全局變量是魔鬼。在YUI中,我們僅用兩個(gè)全局變量:YAHOO和YAHOO_config。YUI的一切都是使用YAHOO對(duì)象級(jí)的成員或這個(gè)成員作用域內(nèi)的變量。我們建議在你的應(yīng)用程序也使用類似的規(guī)則。
Douglas Crockford已經(jīng)傳授了一個(gè)有用的單例模式(singleton pattern)實(shí)現(xiàn)此規(guī)則,我認(rèn)為他的模式有益于你基于YUI的那些應(yīng)用。Douglas叫它模塊模式(module pattern)。它是如下工作的:
1. 創(chuàng)建一個(gè)命名空間對(duì)象:如果你使用YUI,可以用YAHOO.namespace()方法:
YAHOO.namespace("myProject");
這分配了一個(gè)空的myProject對(duì)象,是YAHOO的一個(gè)成員(如 果myProject已存在的話,則不會(huì)被覆蓋)。現(xiàn)在我們可以開始添加YAHOO.myProject的成員。
2. 對(duì)你的命名空間對(duì)象分配一個(gè)匿名函數(shù)返回值:
YAHOO.myProject.myModule = function () { return { myPublicProperty: "我作為YAHOO.myProject.myModule.myPublicProperty被訪問。"; myPublicMethod: function () { YAHOO.log("我作為YAHOO.myProject.myModule.myPublicMethod被訪問。"); } }; }(); // 這個(gè)括號(hào)導(dǎo)致匿名函數(shù)被執(zhí)行且返回
注意有閉合大括號(hào)和緊接著的括號(hào)()的最后一行—這種符號(hào)導(dǎo)致了匿名函數(shù)的立即執(zhí)行,返回包含myPublicProperty和myPublicMethod的對(duì)象。只要這個(gè)匿名函數(shù)一返回,返回對(duì)象就作為YAHOO.myProject.myModule被訪問。
3. 在匿名函數(shù)中,在返回語句前加入“私有”方法和變量。到目前為止,我們只是將myPublicProperty和myPublicMethod直接分配到Y(jié)AHOO.myProject.myModule中。此外,當(dāng)我們?cè)诜祷卣Z句之前放置一些代碼時(shí),這個(gè)模式還支持被增加的效用。
YAHOO.myProject.myModule = function () { //“私有”變量: var myPrivateVar = “我僅能在YAHOO.myProject.myModule內(nèi)被訪問。”; //私有方法: var myPrivateMethod = function () { YAHOO.log(”我僅能在YAHOO.myProject.myModule內(nèi)被訪問!); }
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); } }; }();
在上面的代碼中,我們從一個(gè)匿名函數(shù)返回有兩個(gè)成員的一個(gè)對(duì)象。在YAHOO.myProject.myModule內(nèi)部,可以分別用this.myPublicProperty和this.myPublicMethod來訪問。在YAHOO.myProject.myModule外部,公共成員可以用YAHOO.myProject.myModule.myPublicProperty和YAHOO.myProject.myModule.myPublicMethod來訪問。 私有變量myPrivateProperty和myPrivateMethod只能被匿名函數(shù)本身或返回對(duì)象的成員訪問。盡管匿名函數(shù)會(huì)立即執(zhí)行和終止,但它們依然是保留著,憑借閉包(closure)的力量——通過一個(gè)函數(shù)的局部變量在這個(gè)函數(shù)返回后是保留的規(guī)則。只要 YAHOO.myProject.myModule需要它們,我們的兩個(gè)私有變量就不會(huì)被銷毀。
4. 實(shí)踐這個(gè)模式。讓我們來看看這個(gè)模式的一個(gè)常見應(yīng)用案例。假設(shè)你有一個(gè)列表,列表上的一些項(xiàng)可以被拖拽。應(yīng)用拖拽的項(xiàng)上有拖拽的CSS類。
<!--這個(gè)腳本文件包含所有的YUI實(shí)用程序--> <script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/utilities/ utilities.js"></script> <ul id="myList"> <li class="draggable">一項(xiàng)</li> <li>二項(xiàng)</li> <!--二項(xiàng)將不能被拖拽--> <li class="draggable">三項(xiàng)</li> </ul> <script> YAHOO.namespace("myProject"); YAHOO.myProject.myModule = function () { //YUI實(shí)用程序的私有簡(jiǎn)寫引用: var yue = YAHOO.util.Event, yud = YAHOO.util.Dom; //私有方法 var getListItems = function () { // 注意這個(gè)地方使用其他的私有變量,包括"yud"YAHOO.util.Dom的簡(jiǎn)寫: var elList = yud.get("myList"); var aListItems = yud.getElementsByClassName( "draggable", //得到僅有CSS類"draggable"的項(xiàng) "li", //僅返回列表項(xiàng) elList //限定搜索改元素的子 ); return aListItems; }; //這個(gè)放回的對(duì)象將變成YAHOO.myProject.myModule: return { aDragObjects: [], //可對(duì)外訪問的,存儲(chǔ)DD對(duì)象 init: function () { //直到DOM完全加載好,才實(shí)現(xiàn)列表項(xiàng)可拖拽: 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])); } } }; }(); //上面的代碼已經(jīng)執(zhí)行,所以我們能立即訪問init方法: YAHOO.myProject.myModule.init(); </script>
這是一個(gè)簡(jiǎn)單的例子,特意寫的詳細(xì)一些——如果按照這種方式做,我們無疑能把它寫的更緊湊。當(dāng)項(xiàng)目變得更加復(fù)雜和它的API增加,這個(gè)模式縮放的很好。通過這種方式,它避免了全局命名空間,提供了對(duì)外的可以訪問的API方法,支持受保護(hù)或“私有”的數(shù)據(jù)和方法。
本文鏈接:http://m.95time.cn/tech/web/2007/5169.asp
出處:藍(lán)色理想
責(zé)任編輯:tada
◎進(jìn)入論壇網(wǎng)頁(yè)制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|