2012-02-21 67 views
1

這兩個JavaScript模式非常相似。我想知道哪一個更好,爲什麼以及如何改進。這兩種JavaScript模式之間的優點和缺點是什麼?

第一種方法:

"MODULE" in window || (window.MODULE = {}); 

MODULE.utils = (function ($) { 

    var utils = {}; 

    //public 
    utils.todo = function() { 
     //# 
    } 

    //private 
    function init() { 
     //# 
    } 

    init(); 

    return utils; 
}(jQuery)); 

第二種方法

"MODULE" in window || (window.MODULE = {}); 

MODULE.utils = (function() { 

    function todo(){ 
     //# 
    } 

    function init() { 
     //# 
    } 

    return { 
     init:init 
    } 

})(); 


$(function() { 
    MODULE.utils.init(); 
}); 

回答

4

你的兩個選擇並沒有太多的優點或缺點,更多的是關於個人偏好。兩者都可以調整,以提供更好的範圍。

我有我自己的偏好,它依靠Underscore。它並沒有真正促進私有變量或函數,但我很少發現這是一個問題。如果你想介紹jQuery等,最好用一個匿名函數包裝爲$實際上是jQuery(或可互換的圖書館)。如你在下面看到的,我的首選項需要更多的代碼才能讓你走(儘管有些不是必需的),但是試過了你最初提出的一些變體,我發現我的解決方案使其更易於理解代碼,其他開發人員更容易掌握正在發生的事情,特別是如果他們具有Backbone.View的經驗。

編輯:包裝在一個匿名函數來演示集成jQuery和受保護的範圍。

var MyNamespace = MyNamespace || {}; 

(function($, MyNamespace) { 

    MyNamespace.MyModule = function(options) { 
     this.defaults = this.defaults || {}; 
     // have had trouble with _.defaults so _.extend instead 
     this.options = _.extend({}, this.defaults, options); 
     this.initialize.call(this); 
     // define private stuff in here if you want 
    }; 

    _.extend(MyNamespace.MyModule.prototype, { 

     defaults: { 
      myOption: "test" 
     }, 

     initialize: function() 
     { 
      // ensure this always refers to our MyModule instance 
      _.bindAll(this); 
      this.$el = $("#some-widget"); 
      // Look Ma! log is already binded to this! 
      this.$el.on("click", this.log); 
     }, 

     setMyOption: function(value) 
     { 
      this.options.myOption = value; 
     }, 

     log: function() 
     { 
      console.log("myOption: ", this.options.myOption); 
     } 

    }); 

})(jQuery, MyNamespace) 

var myModule = new MyNamespace.MyModule({ myOption: "Hey SO!" }); 
myModule.log(); // -> myOption: Hey SO! 
myModule.setMyOption("Setter"); 
myModule.log(); // -> myOption: Setter 
1

第二種方法假設名爲$的變量是接受一個參數,這也是一個功能的功能 - 可能是一個假設$ == jQuery。這可能並非總是如此。在第一種方法中,您保證$ == jQuery在您的模塊範圍內,因爲您將它作爲參數傳遞給初始化模塊的匿名函數。

除此之外,兩者之間沒有太大的區別。我更喜歡暴露公共方法的第二種方法,這樣我的語法對於公共方法和私有方法來說都是相同的,所以我必須明確指定哪些方法是公開的。但這只是風格。

2
"MODULE" in window || (window.MODULE = {}); 

爲什麼這樣做?我們已經在全球範圍內這裏,對,所以我們可以這樣做:

var MODULE = MODULE || {}; 

其他的是的是,唯一真正的區別(除了風格以外)是第一個例子init從內馬上打電話「模塊」,而在第二個示例中,在稍後的某個時間點手動調用init(即使在此情況下模塊加載後立即執行)。所以,如果您需要延遲撥打init,第二個是可取的;如果你希望它立即發生,第一個是可取的(除了對風格的偏好)。

相關問題