JavaScriptシリーズを深く理解する3:全面解析Moduleモード
6951 ワード
概要
ModuleモードはJavaScriptプログラミングの中で非常に一般的なモードであり、一般的には基本的な使い方を知っています.本稿ではこのモードの高級な使い方をもっと紹介してみます.
まずModuleモードの基本的な特徴を見てみましょう.モジュール化、 を再利用できます.は、変数と を結合した.は、publicの利用可能な方法のみを暴露し、他のプライベート方法はすべて非表示 である.
Moduleモードについては、最初にYUIのメンバーであるEric Miragliaが2007年頃(原文は4年前、2011年の記事を発表しましたので、まあ4年前です.)というコンセプトを提示しましたが、簡単な例から基本的な使い方を説明します.
基本的な使い方
まず簡単な実現を見てください.コードは以下の通りです.
匿名のクローズド
==匿名のクローズド==すべてが可能な基礎となり、これも
グローバル変数を参照
JavaScript(非厳密モード)は、一つの変数が使用されているかどうかに関わらず、JavaScriptインタプリタが逆方向に作用するドメインチェーンを巡回して全体の変数を検索するという特徴があります.varが見つからなかったら、インタプリタはこの変数がグローバル変数であると仮定します.もしこの変数が赋値操作に使用されていたら、以前は存在しなかったら、インタプリタは自動的にそれを作成します.つまり匿名のクローズドにグローバル変数を使用したり、作成したりするのはとても簡単ですが、コードの管理が難しいです.特にコードを読む人はどの変数が大局的で、どれが局部的なものかを区別して見ています.
しかし、幸いにも匿名関数では比較的簡単な代替案を提供できます.グローバル変数を匿名関数にパラメータとして入力して使用することができます.これは暗黙的なグローバル変数よりも明確で速いです.例を見てみます.
しかし、グローバル変数だけでなく、グローバル変数も宣言したい場合があります.どうすればいいですか?匿名関数の戻り値でこのグローバル変数に戻ります.これは基本的なModuleモードです.完全なコードを見てください.
高級な使い方
上の内容は大多数のユーザーにとって十分ですが、このモードに基づいてより強く、拡張しやすい構造を拡張してもいいです.
拡張
==Moduleモード==の制限の一つはすべてのコードを一つのファイルに書くことです.しかし、いくつかの大型プロジェクトでは、一つの機能を複数のファイルに分離することが重要です.複数の人が協力して開発しやすいからです.上記のグローバルパラメータ導入例を振り返ってみます.BlogModule自身を紹介してもいいですか?答えは肯定的です.私達は先にBLogModuleを伝えて、関数の属性を追加して、それから戻ってきます.
松結合拡張
上のコードは実行できますが、先にBLogModuleを声明してから上の拡張コードを実行しなければなりません.つまりステップが乱れてはいけません.どうやってこの問題を解決しますか?私たちが普段宣言している変数は全部このようなものです.
結合拡張
松の結合が大きくなりましたが、いくつかの制限があります.例えば、あなたの属性や関数の一部を書き換えることができません.初期化の時にModuleの属性を使うこともできません.緊密結合拡張は負荷順序を制限していますが、再負荷の機会を提供しています.次の例を参照してください.
クローンと継承
ファイルにまたがってプライベートオブジェクトを共有する
上記の例を通して、もし一つのmoduleが複数のファイルに分割されたら、各ファイルは同じ構造を保証しなければならないということを知っています.つまり、各ファイルの匿名関数の中のプライベートオブジェクトは互いに訪問できません.まずコードを見ます.
サブモジュール
最後の一つは最も簡単な使い方です.サブモジュールを作ることです.
締め括りをつける
上記の大部分の方法は互いに組み合わせて使用することができます.一般的にシステムを設計するには、松結合拡張、プライベート状態、サブモジュールという方法が使われるかもしれません.また、性能については言及していませんが、Moduleモードの効率が高く、コードが少なく、ロード速度が速いと思います.松結合拡張を使用すると並列負荷が可能になり、よりダウンロード速度が向上します.初期化時間は少し遅いかもしれませんが、良いモードを使うためには価値があります.
参考文献:http://yuiblog.com/blog/2007/06/12/module-pattern/ http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
本稿について
本論文はTOMおじさんのJavaScriptシリーズを深く理解するから回転する.
【JavaScriptシリーズを深く理解する】文章には、オリジナル、翻訳、転載、整理などの各タイプの文章が含まれています.ありがとうございます.
ModuleモードはJavaScriptプログラミングの中で非常に一般的なモードであり、一般的には基本的な使い方を知っています.本稿ではこのモードの高級な使い方をもっと紹介してみます.
まずModuleモードの基本的な特徴を見てみましょう.
function
をカプセル化し、大域的なnamaspaceとは接触せずに、デカップリングModuleモードについては、最初にYUIのメンバーであるEric Miragliaが2007年頃(原文は4年前、2011年の記事を発表しましたので、まあ4年前です.)というコンセプトを提示しましたが、簡単な例から基本的な使い方を説明します.
基本的な使い方
まず簡単な実現を見てください.コードは以下の通りです.
var Calculator = function (eq) {
//
var eqCtl = document.getElementById(eq);
return {
//
add: function (x, y) {
var val = x + y;
eqCtl.innerHTML = val;
}
};
};
私たちは次のように呼び出すことができます.var calculator = new Calculator('eq');
calculator.add(2, 2);
使用するたびにnewしてください.つまり各インスタンスはメモリ内でcopyです.パラメータや特別な要求がないなら、最後の}の後ろに括弧を入れて、自己実行の目的に達することができます.このようにメモリにはcopyしか存在しません.彼の長所を示す前に、このパターンの基本的な使い方を見てみましょう.匿名のクローズド
==匿名のクローズド==すべてが可能な基礎となり、これも
JavaScript
の最も良い特性であり、最も簡単なクローズド関数を作成します.関数内部のコードは常にクローズドされています.このクローズドは内部コードがプライベート状態にあることを保証します.(function () {
// ... function ,
// ...
}());
匿名関数の後ろの括弧はJavaScript言語で要求されています.もしあなたが声明しないなら、JavaScript解釈器はデフォルトではfunction関数を宣言しています.括弧があります.関数式を作成します.つまり、自己実行します.使う時は上のようにnewにしなくてもいいです.もちろん、あなたもこのように声明してもいいです.(function () {/* */})();
しかし、最初の方法を勧めます.関数の自己実行については、後に専門的な文章があります.ここで詳しく説明しません.グローバル変数を参照
JavaScript(非厳密モード)は、一つの変数が使用されているかどうかに関わらず、JavaScriptインタプリタが逆方向に作用するドメインチェーンを巡回して全体の変数を検索するという特徴があります.varが見つからなかったら、インタプリタはこの変数がグローバル変数であると仮定します.もしこの変数が赋値操作に使用されていたら、以前は存在しなかったら、インタプリタは自動的にそれを作成します.つまり匿名のクローズドにグローバル変数を使用したり、作成したりするのはとても簡単ですが、コードの管理が難しいです.特にコードを読む人はどの変数が大局的で、どれが局部的なものかを区別して見ています.
しかし、幸いにも匿名関数では比較的簡単な代替案を提供できます.グローバル変数を匿名関数にパラメータとして入力して使用することができます.これは暗黙的なグローバル変数よりも明確で速いです.例を見てみます.
(function ($, YAHOO) {
// , jQuery ,YAHOO
} (jQuery, YAHOO));
今は多くの種類の倉庫にこのような使い方があります.例えば、jQueryのソースコードです.しかし、グローバル変数だけでなく、グローバル変数も宣言したい場合があります.どうすればいいですか?匿名関数の戻り値でこのグローバル変数に戻ります.これは基本的なModuleモードです.完全なコードを見てください.
var blogModule = (function () {
var my = {}, privateName = "segmentfault";
function privateAddTopic(data) {
//
}
my.Name = privateName;
my.AddTopic = function (data) {
privateAddTopic(data);
};
return my;
} ());
上のコードは大域変数blogModuleを声明しており、2つのアクセス可能な属性を持っています.blog Module.AddTopicとblogModule.Nameはこれ以外のコードは匿名関数のクローズドに私有状態を維持しています.また、上記の大域変数の例によって、他の大域変数にも簡単に入ることができます.高級な使い方
上の内容は大多数のユーザーにとって十分ですが、このモードに基づいてより強く、拡張しやすい構造を拡張してもいいです.
拡張
==Moduleモード==の制限の一つはすべてのコードを一つのファイルに書くことです.しかし、いくつかの大型プロジェクトでは、一つの機能を複数のファイルに分離することが重要です.複数の人が協力して開発しやすいからです.上記のグローバルパラメータ導入例を振り返ってみます.BlogModule自身を紹介してもいいですか?答えは肯定的です.私達は先にBLogModuleを伝えて、関数の属性を追加して、それから戻ってきます.
var blogModule = (function (my) {
my.AddPhoto = function () {
//
};
return my;
} (blogModule));
このコードは、Cの拡張方法のような感じがしますか?似ていますが、本質は違いますよ.同時に、varは必須ではないが、一致を確保するために、コード実行後、blogModule
の下のAddPhoto
が使用できるようになり、匿名関数内部のコードも依然としてプライバシーと内部状態を保証している.松結合拡張
上のコードは実行できますが、先にBLogModuleを声明してから上の拡張コードを実行しなければなりません.つまりステップが乱れてはいけません.どうやってこの問題を解決しますか?私たちが普段宣言している変数は全部このようなものです.
var cnblogs = cnblogs || {} ;
これはcnblogsオブジェクトが存在する時に直接使用されることを確認しています.存在しない時に直接値を「%」として付与します.この特性を利用してModuleモードの任意のロード順序を実現するにはどうすればいいですか?var blogModule = (function (my) {
//
return my;
} (blogModule || {}));
このようなコードを通して、個々に分離されたファイルごとにこの構造を保証します.そうすると、任意の順序でロードすることができます.だから、この時のvarは声明が必要です.結合拡張
松の結合が大きくなりましたが、いくつかの制限があります.例えば、あなたの属性や関数の一部を書き換えることができません.初期化の時にModuleの属性を使うこともできません.緊密結合拡張は負荷順序を制限していますが、再負荷の機会を提供しています.次の例を参照してください.
var blogModule = (function (my) {
var oldAddPhotoMethod = my.AddPhoto;
my.AddPhoto = function () {
// , oldAddPhotoMethod
};
return my;
} (blogModule));
このような方法によって、私達は重積載の目的を達成しました.もちろん内部で既存の属性を使い続けたいなら、oldAdd PhotoMethodを呼び出すことができます.クローンと継承
var blogModule = (function (old) {
var my = {},
key;
for (key in old) {
if (old.hasOwnProperty(key)) {
my[key] = old[key];
}
}
var oldAddPhotoMethod = old.AddPhoto;
my.AddPhoto = function () {
// , , oldAddPhotoMethod
};
return my;
} (blogModule));
このような方式は柔軟ですが、柔軟な代価が必要です.実はこの対象の属性オブジェクトやfunctionはまったくコピーされていません.同じ対象に対して一つの引用が多いだけです.だから、もし古いオブジェクトがそれを変えたら、クローン後の対象が持つ属性やfunction関数も変更されます.この問題を解決するためには、再帰を利用しなければなりません.しかし、再帰的にはfunction関数の割り当てもよくないので、再帰的にはeval対応のfunctionです.いずれにしても、私はやはりこの方式をこの招待状の中に置いて、みんなが使う時注意してください.ファイルにまたがってプライベートオブジェクトを共有する
上記の例を通して、もし一つのmoduleが複数のファイルに分割されたら、各ファイルは同じ構造を保証しなければならないということを知っています.つまり、各ファイルの匿名関数の中のプライベートオブジェクトは互いに訪問できません.まずコードを見ます.
var blogModule = (function (my) {
var _private = my._private = my._private || {},
_seal = my._seal = my._seal || function () {
delete my._private;
delete my._seal;
delete my._unseal;
},
_unseal = my._unseal = my._unseal || function () {
my._private = _private;
my._seal = _seal;
my._unseal = _unseal;
};
return my;
} (blogModule || {}));
どのファイルも彼らのローカル変数に対応できます.prvateは属性を設定し、他のファイルに対してもすぐに有効になります.このモジュールのロードが完了すると、アプリケーションはblogModule._を呼び出します.seal()「鍵をかける」と、外部からの内部へのアクセスを阻害します.prvateこのモジュールが再増殖する必要がある場合は、アプリケーションのライフサイクル内で、どのファイルでも呼び出しできます.unseal()「ロックを解除」して、新しいファイルをロードします.読み込み後、再度呼び出します.「鍵をかける」.サブモジュール
最後の一つは最も簡単な使い方です.サブモジュールを作ることです.
blogModule.CommentSubModule = (function () {
var my = {};
// ...
return my;
} ());
非常に簡単ですが、それを入れました.サブモジュールも一般モジュールのすべての高級な使い方を持っていると説明したいです.つまり、どのサブモジュールに対しても上のいくつかの応用方法をもう一回使ってもいいです.締め括りをつける
上記の大部分の方法は互いに組み合わせて使用することができます.一般的にシステムを設計するには、松結合拡張、プライベート状態、サブモジュールという方法が使われるかもしれません.また、性能については言及していませんが、Moduleモードの効率が高く、コードが少なく、ロード速度が速いと思います.松結合拡張を使用すると並列負荷が可能になり、よりダウンロード速度が向上します.初期化時間は少し遅いかもしれませんが、良いモードを使うためには価値があります.
参考文献:http://yuiblog.com/blog/2007/06/12/module-pattern/ http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
本稿について
本論文はTOMおじさんのJavaScriptシリーズを深く理解するから回転する.
【JavaScriptシリーズを深く理解する】文章には、オリジナル、翻訳、転載、整理などの各タイプの文章が含まれています.ありがとうございます.