2012-02-21 14 views
1

これらの2つのJavaScriptパターンは非常に似ています。私はどちらが良いか、なぜどちらが改善できるのかを知りたい。この2つの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の経験がある場合には、より理解しやすいコードに役立ちます。

EDIT: 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

第2のアプローチは、$という名前の変数は、関数である単一の引数を取る関数であると仮定し - おそらくその仮定は$ == jQueryです。これは常に正しいとは限りません。最初のアプローチでは、モジュールを初期化する匿名関数の引数として渡すので、モジュールのスコープ内で$ == jQueryを保証します。

それ以外では、2つの間に大きな違いはありません。私はパブリックメソッドを公開するための第2のアプローチを選択して、パブリックメソッドとプライベートメソッドの両方で構文が同じように見えるようにし、どのメソッドがpublicであるかを明示的に指定する必要があります。しかしそれはただの文体です。

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

なぜそれを行いますか?我々は右、ここではグローバルスコープですでにしているので、我々は単に行うことができます。

(スタイル以外)は、唯一の本当の違いは、最初の例では initがすぐに内から呼び出されていることを他の
var MODULE = MODULE || {}; 

を"モジュール"と呼びますが、2番目の例では、を後で(モジュールがこの場合にロードされた直後であっても)手動で呼び出します。したがって、initへのコールを遅らせる必要がある場合は、2番目が好ましいです。それがすぐに起こるようにするには、最初のスタイルが好ましいです(スタイルに関する設定を除いて)。

関連する問題