2013-07-21 14 views
118

2つ(またはそれ以上)の異なるモジュールがどのように連携して動作するかを示す例が見つかりません。例を含むJavaScriptモジュールパターン

だから、誰かがモジュールがどのように連動するかを説明する例を書く時間があるかどうか質問したいと思います。

+0

これは、すべての最後の4年間で変化しているが、過剰節度熱心なのおかげで、この期限切れの情報がハングします周り*永遠に*。 ES6モジュールの[MDNのページ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)です。 – bbsimonbb

答えて

237

モジュラーデザインパターンに近づけるためには、まずこれらの概念を理解する必要があります。

直後、呼び出される関数の式(生命維持):

(function() { 
     // Your code goes here 
}()); 

あなたが機能を使用できる2つの方法があります。 。 1.関数宣言2.関数定義。 ここでは関数定義式を使用しています。

名前空間とは何ですか?私たちはその後、上記のコード片に名前空間を追加する場合 今

var anoyn = (function() { 
}()); 

閉鎖はJSで何ですか?

可変スコープの/他の関数の中でJSを宣言すると、そのスコープは常にカウントされます。つまり、外部関数の変数は常に読み取られます。同じ名前のグローバル変数(存在する場合)は読み込まれません。これはまた、ネーミングの競合を避けるモジュラー設計パターンを使用する目的の1つです。

var scope = "I am global"; 
function whatismyscope() { 
    var scope = "I am just a local"; 
    function func() {return scope;} 
    return func; 
} 
whatismyscope()() 

今、私たちは私たちの最初のモジュール設計パターンを定義するために、私は上記のこれらの3つのコンセプトを適用します。

var modularpattern = (function() { 
    // your module code goes here 
    var sum = 0 ; 

    return { 
     add:function() { 
      sum = sum + 1; 
      return sum; 
     }, 
     reset:function() { 
      return sum = 0;  
     } 
    } 
}()); 
alert(modularpattern.add()); // alerts: 1 
alert(modularpattern.add()); // alerts: 2 
alert(modularpattern.reset()); // alerts: 0 

jsfiddle for the code above.

目的は外の世界からの変数のアクセスを非表示にすることです。

これが役に立ちます。がんばろう。

「学習JavaScriptのデザインパターン」:

+0

アイフルの名前を付けた方がいいですか?意味論的目的とスタックトレースの向上のために?それはコード内の何かを変えるでしょうか? – Jeroen

+2

あなたの最初の例 '(function(){/ *あなたのコードはここに入ります* /}());'は実際にはIIFE(即座に呼び出す関数式)です。それはIIAFE(即座に匿名関数式を呼び出す)では、IIFEについての詳細はhttp://stackoverflow.com/questions/2421911/what-is-the-purpose-of-wrap-whole-javascript-files-in-anonymous-functionsを参照してください。 -li/26738969#26738969 –

+0

なぜreturn文が使用されましたか?私たちがreturn {}を省略すると、関数を追加してリセットするとpublicになり、ローカル変数sumにアクセスできますか?私は正しい? – Mou

36

は、私は本当にこの主題に入る誰でもアディOsmaniの自由な本を読むことをお勧めします。私はより保守JavaScriptを書くに開始されたときに

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

この本は非常に私を助け、私はまだそれを参照として使用します。彼のさまざまなモジュールパターンの実装を見て、本当にうまく説明します。

+0

Addy Osmaniの本でカバーされていない「Definitive Module Pattern」の記事を読むことをお勧めします。 https://github.com/tfmontague/definitive-module-pattern – tfmontague

+0

これは「JavaScriptパターン"Stoyan Stefanov著 – JohnMerlino

+3

Stoyanの本ははるかに包括的です。それは単なる高水準のパターン以上のものをカバーしますが、他のJSのベストプラクティスについてより深く語ります。 "Learning JavaScript Design Patterns"の –

16

私はあなたがモジュールをアプリケーションに合わせる方法について話して、上記の答えを広げたいと考えました。私はdoug crockfordの本でこれについて読むだろうが、それはまだ少し神秘的なすべてだったjavascriptに新しいです。

私はC#の背景から来ましたので、そこから有用ないくつかの用語を追加しました。

Htmlの

あなたは、いくつかのkindofがトップレベルのhtmlファイルがあるでしょう。これをあなたのプロジェクトファイルと考えることができます。あなたがプロジェクトに追加するすべてのjavascriptファイルは、この中に入りたいと思っています。残念ながら、私はIDEAを使っています。

あなたは、このようなスクリプトタグをプロジェクトにファイルを追加する必要があります。

 <script type="text/javascript" src="app/native/MasterFile.js" /></script> 
     <script type="text/javascript" src="app/native/SomeComponent.js" /></script> 

それタグを崩壊することは、物事が失敗する表示されます - それは、XMLのように見えながら、それは本当にスゴルールで何かです!それだ

名前空間ファイル

MasterFile.js

myAppNamespace = {}; 

。これは、コードの残りの部分に1つのグローバル変数を追加するためのものです。ネストした名前空間をここに(または自分のファイルに)宣言することもできます。

モジュール(複数可)

SomeComponent.js

myAppNamespace.messageCounter= (function(){ 

    var privateState = 0; 

    var incrementCount = function() { 
     privateState += 1; 
    }; 

    return function (message) { 
     incrementCount(); 
     //TODO something with the message! 
    } 
})(); 

私たちがここでやっていることは我々のアプリケーション内の変数にメッセージカウンター機能を割り当てています。 がすぐにを実行する関数を返す関数です。

概念

私はそれはあなたが何かを宣言している名前空間としてSomeComponentで一番上の行を考えるのに役立ちますだと思います。これに対する唯一の注意点は、すべての名前空間が他のファイルに最初に表示される必要があることです。それらはアプリケーション変数を根源とするオブジェクトです。

私は現時点でこれをマイナーチェンジしました(私はそれをテストできるように、通常のjavascriptをいくつかリファクタリングしています)が、少し機能的なユニットを定義することができますの「この「」の泥沼。

また、このスタイルを使用すると、関数のコレクションを持つオブジェクトを返し、すぐには呼び出さない関数を返すことで、コンストラクターを定義できます。

6

ここでhttps://toddmotto.com/mastering-the-module-patternは完全に説明されたパターンを見つけることができます。私は、モジュラーJavaScriptについての2番目のことは、複数のファイルでコードを構造化する方法だと付け加えます。多くの人々がここでAMDに行くようアドバイスするかもしれませんが、経験から言うと、多くのHTTPリクエストのためにページの応答が遅くなることがあります。解決方法は、JavaScriptモジュール(ファイルごとに1つ)をCommonJS標準に従って1つのファイルに事前にコンパイルすることです。あなたはモジュールのパターンはJavaScriptを見つけることができ、ここでhttp://dsheiko.github.io/cjsc/

+0

すべてのAMD実装では、1つのファイルにプリコンパイルも提供されています。 –

+1

これは正しいですが、結果として最適化されたファイルには、通常はかなり重いローダーライブラリが必要です(r.js v2.1.14で再確認してください)。コードをコンパイルするとすぐに、非同期にロードされた依存関係を解決する必要はありません。このライブラリは不要です。モジュールをAMDにラップすることは、非同期を意味します。それらを単一のファイルにコンパイルします(個別のロードはもう必要ありません)。ただし、ライブラリ全体をロードしてそれらに対処します(今は冗長です)。それは私にとって最適な方法としては聞こえません。私たちが非同期にロードしないときは、なぜAMDですか? –

+0

almond.jsは、RequireJSより完成したプロダクションコードのためのより小さいウェイトローダーを提供しますが、比較的簡単に言えば、単一のHTTPリクエストを作成しないというパフォーマンス上の利点は、ローダーコードをモジュールに追加するコストをはるかに上回ります。それははるかに小さい規模です。 私の意見では、ブラウザーがそうでないときに、なぜ同調性を仮定するのかといえます。私は、実際には、RequireJSとCommonJSの両方に、約束の実装が組み込まれていなければならないとの意見があります。 –

関連する問題