学習ノート(3)_全面解析モード
11398 ワード
概要
ModuleモードはJavaScriptプログラミングの中で非常に一般的なモードであり、一般的には基本的な使い方を知っています.本稿ではこのモードの高級な使い方をもっと紹介してみます.
まずModuleモードの基本的な特徴を見てみましょう.モジュール化、 を再利用できます.には変数とfunctionが封入されています.全体のnamastpaceとは接触していません. は、publicの利用可能な方法のみを暴露し、他のプライベート方法はすべて非表示 である.
基本的な使い方
まず簡単な実現を見てください.コードは以下の通りです.
私たちは次のように呼び出すことができます.
匿名のクローズド
匿名のクローズドは、すべてを可能な基礎にすることであり、これもJavaScriptの最も良い特性であり、最も簡単なクローズド関数を作成します.関数内部のコードはずっとクローズド内に存在しています.このクローズドはすべて内部のコードがプライベート状態にあることを保証します.
グローバル変数を参照
JavaScriptには暗黙的大域変数という特性があります.一つの変数が使用されたかどうかに関わらず、JavaScriptインタプリタが逆方向に作用するドメインチェーンを巡回して全体の変数を検索するvar宣言があります.もしvarが見つからなかったら、インタプリタは大域変数だと仮定します.もしこの変数が赋値操作に使われたなら、前に存在しなかったら、インタプリタは自動的に作成されます.つまり匿名のクローズドにグローバル変数を使用したり、作成したりするのは簡単ですが、コードは管理しにくいです.特にコードを読んでいる人は、どの変数が大局的で、どれが局部的なものかを区別することが多いです.しかし、幸いにも匿名関数では比較的簡単な代替案を提供できます.グローバル変数を匿名関数にパラメータとして入力して使用することができます.これは暗黙的なグローバル変数よりも明確で速いです.例を見てみます.
しかし、グローバル変数だけでなく、グローバル変数も宣言したい場合があります.どうすればいいですか?匿名関数の戻り値でこのグローバル変数に戻ります.これは基本的なModuleモードです.完全なコードを見てください.
ModuleモードはJavaScriptプログラミングの中で非常に一般的なモードであり、一般的には基本的な使い方を知っています.本稿ではこのモードの高級な使い方をもっと紹介してみます.
まずModuleモードの基本的な特徴を見てみましょう.
基本的な使い方
まず簡単な実現を見てください.コードは以下の通りです.
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宣言があります.もしvarが見つからなかったら、インタプリタは大域変数だと仮定します.もしこの変数が赋値操作に使われたなら、前に存在しなかったら、インタプリタは自動的に作成されます.つまり匿名のクローズドにグローバル変数を使用したり、作成したりするのは簡単ですが、コードは管理しにくいです.特にコードを読んでいる人は、どの変数が大局的で、どれが局部的なものかを区別することが多いです.しかし、幸いにも匿名関数では比較的簡単な代替案を提供できます.グローバル変数を匿名関数にパラメータとして入力して使用することができます.これは暗黙的なグローバル変数よりも明確で速いです.例を見てみます.
(function ($, YAHOO) {
// , jQuery ,YAHOO
} (jQuery, YAHOO));
今は多くの種類の倉庫にこのような使い方があります.例えば、jQueryのソースコードです.しかし、グローバル変数だけでなく、グローバル変数も宣言したい場合があります.どうすればいいですか?匿名関数の戻り値でこのグローバル変数に戻ります.これは基本的なModuleモードです.完全なコードを見てください.
上のコードは大域変数blogModuleを声明しており、2つのアクセス可能な属性を持っています.blog Module.AddTopicとblogModule.Nameはこれ以外のコードは匿名関数のクローズドに私有状態を維持しています.また、上記の大域変数の例によって、他の大域変数にも簡単に入ることができます.var blogModule = (function () { var my = {}, privateName = " "; function privateAddTopic(data) { // } my.Name = privateName; my.AddTopic = function (data) { privateAddTopic(data); }; return my; } ());
高級な使い方
上の内容は大多数のユーザーにとって十分ですが、このモードに基づいてより強く、拡張しやすい構造を拡張してもいいです.
拡張
Moduleモードの制限の一つはすべてのコードを一つのファイルに書くことです.しかし、いくつかの大型プロジェクトでは、一つの機能を複数のファイルに分離することが重要です.複数の人が協力して開発しやすいからです.上記のグローバルパラメータ導入例を振り返ってみます.BlogModule自身を紹介してもいいですか?答えは肯定的です.私達は先にBLogModuleを伝えて、関数の属性を追加して、それから戻ってきます.このコードは、Cの拡張方法のような感じがしますか?似ていますが、本質は違いますよ.また、varは必須ではないが、一致を確保するために、コードを再使用して、BlogModuleのAdd Photooで使用できます.また、匿名関数内部のコードも依然としてプライバシーと内部状態を保証しています.var blogModule = (function (my) { my.AddPhoto = function () { // }; return my; } (blogModule));
松結合拡張
上のコードは実行できますが、先にBLogModuleを声明してから上の拡張コードを実行しなければなりません.つまりステップが乱れてはいけません.どうやってこの問題を解決しますか?私たちが普段宣言している変数は全部このようなものです.これはcnblogsオブジェクトを確保し、存在する時に直接使用し、存在しない時に直接値を「%」として付与します.この特性を利用してModuleモードの任意のロード順序を実現する方法を見てみます.var cnblogs = cnblogs || {} ;
このようなコードを通して、個々に分離されたファイルごとにこの構造を保証します.そうすると、任意の順序でロードすることができます.だから、この時のvarは声明が必要です.var blogModule = (function (my) { // return my; } (blogModule || {}));
結合拡張
松の結合が大きくなりましたが、いくつかの制限があります.例えば、あなたの属性や関数の一部を書き換えることができません.初期化の時にModuleの属性を使うこともできません.緊密結合拡張は負荷順序を制限していますが、再負荷の機会を提供しています.次の例を参照してください.このような方法によって、私達は重積載の目的を達成しました.もちろん内部で既存の属性を使い続けたいなら、oldAdd PhotoMethodを呼び出すことができます.var blogModule = (function (my) { var oldAddPhotoMethod = my.AddPhoto; my.AddPhoto = function () { // , oldAddPhotoMethod }; return my; } (blogModule));
クローンと継承このような方式は柔軟ですが、柔軟な代価が必要です.実はこの対象の属性オブジェクトやfunctionはまったくコピーされていません.同じ対象に対して一つの引用が多いだけです.だから、もし古いオブジェクトがそれを変えたら、クローン後の対象が持つ属性やfunction関数も変更されます.この問題を解決するためには、再帰を利用しなければなりません.しかし、再帰的にはfunction関数の割り当てもよくないので、再帰的にはeval対応のfunctionです.いずれにしても、私はやはりこの方式をこの招待状の中に置いて、みんなが使う時注意してください.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));
ファイルにまたがってプライベートオブジェクトを共有する
上記の例を通して、もし一つのmoduleが複数のファイルに分割されたら、各ファイルは同じ構造を保証しなければならないということを知っています.つまり、各ファイルの匿名関数の中のプライベートオブジェクトは互いに訪問できません.まずコードを見ます.どのファイルも彼らのローカル変数に対応できます.prvateは属性を設定し、他のファイルに対してもすぐに有効になります.このモジュールのロードが完了すると、アプリケーションはblogModule._を呼び出します.seal()「鍵をかける」と、外部からの内部へのアクセスを阻害します.prvateこのモジュールが再増殖する必要がある場合は、アプリケーションのライフサイクル内で、どのファイルでも呼び出しできます.unseal()「ロックを解除」して、新しいファイルをロードします.読み込み後、再度呼び出します.「鍵をかける」.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 || {}));
サブモジュール
最後の一つは最も簡単な使い方です.サブモジュールを作ることです.非常に簡単ですが、それを入れました.サブモジュールも一般モジュールのすべての高級な使い方を持っていると説明したいです.つまり、どのサブモジュールに対しても上のいくつかの応用方法をもう一回使ってもいいです.blogModule.CommentSubModule = (function () { var my = {}; // ... return my; } ());
締め括りをつける
上記の大部分の方法は互いに組み合わせて使用することができます.一般的にシステムを設計するには、松結合拡張、プライベート状態、サブモジュールという方法が使われるかもしれません.また、性能については言及していませんが、Moduleモードの効率が高く、コードが少なく、ロード速度が速いと思います.松結合拡張を使用すると並列負荷が可能になり、よりダウンロード速度が向上します.初期化時間は少し遅いかもしれませんが、良いモードを使うためには価値があります.