A JavaScript Module Pattern – JavaScript的一種組件模式

來源:互聯網
上載者:User
原文出處:http://yuiblog.com/blog/2007/06/12/module-pattern/
翻譯:Frank
全域變數是一種禍害。在YUI中,我們只使用兩個全域變數YAHOO和YAHOO_config。所有YUI的對象都從YAHOO這個對象層次上訪問成員或屬於這個成員的變數。我們建議你在您的程式中亦效仿此實踐。
Douglas Crockford已經對我們傳授了使用單例的模式(singletion pattern)來實現此模式,而且我認為應用到該模式來構建基於YUI,不乏一些有意思的地方。Douglas稱這個為“”,看看他怎麼做的?

1、建立命名空間對象:如果你使用的YUI,你可以採用的YAHOO.namespace()的方法:

js 代碼
 
  1.   
  2. YAHOO.namespace("myProject");  


這分配了一個空的myProject對象,是YAHOO的一個成員(但不會覆蓋myProject如果已存在的話)。現在我們可以開始加入YAHOO.myProject成員。

 

2、從一個匿名函數傳回值,分配到命名空間對象上

js 代碼
  1.   
  2. YAHOO.myProject.myModule = function () {   
  3.  return  {   
  4.   myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty.";   
  5.   myPublicMethod: function () {   
  6.    YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");   
  7.   }   
  8.  };   
  9. }(); //這裡括弧的作用的是 執行該匿名函數並返回  

注意花括弧結尾的最底行,後面緊跟著一對括弧() --這符號的含意是立即執行該匿名函數,返回一個包含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。

  1. <!--This script file includes all of the YUI utilities:-->  
  2. <script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/utilities/utilities.js"></script>  
  3.   
  4. <ul id="myList">  
  5.     <li class="draggable">Item one.</li>  
  6.     <li>Item two.</li> <!--item two won't be draggable-->  
  7.     <li class="draggable">Item three.</li>  
  8. </ul>  
  9.   
  10. <script>  
  11. YAHOO.namespace("myProject");   
  12. YAHOO.myProject.myModule = function () {   
  13.   
  14.     //引用YUI utilities的簡寫:   
  15.     var yue = YAHOO.util.Event,   
  16.           yud = YAHOO.util.Dom;   
  17.   
  18.     //私人方法   
  19.     var getListItems = function () {   
  20.   
  21.         //注意我們使用其它的私人變數,包括 "yud"的簡寫   
  22.         var elList = yud.get("myList");   
  23.         var aListItems = yud.getElementsByClassName(   
  24.             "draggable", //擷取只帶有”draggable“CSS類的item   
  25.             "li", //只返回列表item   
  26.             elList //限制搜尋該元素的children   
  27.         );   
  28.         return aListItems;   
  29.     };   
  30.   
  31.     //返回的對象變為YAHOO.myProject.myModule:   
  32.     return  {   
  33.   
  34.         aDragObjects: [], //儲存 DD objects,可對外訪問   
  35.   
  36.         init: function () {   
  37.             //等到DOM完全載入好,才開始建立列表item:   
  38.             yue.onDOMReady(this.makeLIsDraggable, this, true);   
  39.         },   
  40.   
  41.         makeLIsDraggable: function () {   
  42.             var aListItems = getListItems(); //這些元素我們讓它可拖動   
  43.             for (var i=0, j=aListItems.length; i<j; i++) {   
  44.                 this.aDragObjects.push(new YAHOO.util.DD(aListItems[i]));   
  45.             }   
  46.         }   
  47.   
  48.     };   
  49. }(); //這裡括弧的作用的是 執行該匿名函數並返回   
  50.   
  51. //上面的代碼執行完畢,所以我們即可訪問init   
  52. YAHOO.myProject.myModule.init();   
  53. </script>  
xml 代碼
這個一個簡單的例子,特意寫得繁瑣一些。如果我們按這種方式做,我們有相信能夠寫出更緊湊的代碼。不過,該模式的伸縮 會隨著項目的複雜度同步增長,API也變得越來越大。使用該方法,避免的了全域的命名空間,而又能對API的方法公用的訪問,支援保護(protected)或”私人“的資料。

 

 

js 代碼
  1.   
  2. YAHOO.myProject.myModule = function () {   
  3.  //“私人變數”:   
  4.  var myPrivateVar = "I can be accessed only from within YAHOO.myProject.myModule.";   
  5.  //“私人方法”:   
  6.  var myPrivateMethod = function () {   
  7.   YAHOO.log("I can be accessed only from within YAHOO.myProject.myModule");   
  8.  }   
  9.  return  {   
  10.   myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty."  
  11.   myPublicMethod: function () {   
  12.    YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");   
  13.    //Within myProject, I can access "private" vars and methods:   
  14.    YAHOO.log(myPrivateVar);   
  15.    YAHOO.log(myPrivateMethod());   
  16.    //The native scope of myPublicMethod is myProject; we can   
  17.    //access public members using "this":   
  18.    YAHOO.log(this.myPublicProperty);   
  19.   }   
  20.  };   
  21. }(); //這裡括弧的作用的是 執行該匿名函數並返回   

上面的代碼中,我們從一匿名函數返回一個包含兩個成員的對象。在YAHOO.myProject.myModule內可分別用this.myPublicProperty和this.myPublivMethod來訪問。在YAHOO.myProject.myModule外部,這些公告成員可用YAHOO.myProject.myModule.myPublicProperty 和 YAHOO.myProject.myModule.myPublicMethod訪問。 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.