ホームページ > 記事 > ウェブフロントエンド > jQuery コア アーキテクチャ設計に関する簡単な説明
jQuery は誰にとっても馴染みのあるものではないため、ここでは jQuery が何であるか、またその機能については多くを説明しません。この記事の目的は、ソース コードの簡単な分析を通じて jQuery のコア アーキテクチャ設計について説明することです。 jQuery が JavaScript の高度な機能をどのように利用して、このような優れた JavaScript ライブラリを構築するか。
1 jQuery の最初の紹介
コア関数の観点から見ると、jQuery は 1 つの単純で普通のこと、つまりクエリのみを実行します。その構文は非常に簡潔かつ明確であるため、JavaScript が何であるかを知らずに jQuery を使用している人は、一言で言えば「シンプルでシンプル」です。 設計の観点から見ると、jQuery が提供するメソッドは、静的メソッドとインスタンス メソッドという 2 つの主要なカテゴリに分類できます。静的メソッドは、$ を介して直接アクセスされるメソッドです。これらのメソッドは通常、DOM 要素を操作しませんが、ajax リクエストや文字列に対するいくつかの一般的な操作などのいくつかの共通ツールを提供します。さらに、jQuery は独自の拡張メカニズムも提供します。 extend メソッドを通じて必要なコンポーネントを記述します。インスタンス メソッドは静的メソッドとは異なり、jQuery によってクエリされた DOM 要素を操作するために使用されます。jQuery は $() を実行して、クエリされたすべての DOM 要素を配列メソッドに格納します。 this オブジェクトのプロトタイプ チェーンは、これらの DOM を操作するためのメソッドを実装します。たとえば、各 DOM 要素を走査するために each() メソッドが使用されます。このオブジェクトは「配列として」格納される、つまり、jQuery によって構築されたオブジェクトは配列ではない、と先ほど述べたことに気づいたかもしれません。では、このオブジェクトは正確には何でしょうか? 実際、このオブジェクトは jQuery の核心であり、「jQuery オブジェクト」とも呼ばれます。したがって、この記事の焦点は、jQuery オブジェクトを分析して説明することです。
2 jQuery オブジェクト
通常、jQuery は次のように使用します。
$('div').each(function(index){ //this ...});
$('div') は、実行後に jQuery オブジェクトを返します。 each() メソッドは、このオブジェクト内の DOM を変更します。要素をたどって、まず $('div') の実行プロセスを見てみましょう (この記事のソース コードは jQuery 3.0 から取得しています):
jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); }
このメソッドは $('div') のエントリ メソッドです, $ は jQuery の略語で、jQuery('div') と同等です。このメソッドは、jQuery.fn.init() 関数のインスタンス オブジェクトを返すという 1 つのことだけを行うことがわかります。以下のコードを見てみましょう:
init = jQuery.fn.init = = jQuery.fn;
jQuery.fn.init は、セレクターに基づいて修飾された DOM 要素を照会し、それらを返します。返されたものはこれです、これは何ですか?後で分析します: まず、次の文を見てみましょう:
init.prototype = jQuery.fn;
この文は何を意味しますか? この文は、init メソッドのプロトタイプ オブジェクトが jQuery.fn オブジェクトを指すようにしています。おばけ? コードを見ていきましょう:
jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, // Execute a callback for every element in the matched set. each: function( callback ) { return jQuery.each( this, callback ); }, splice: arr.splice };
スペースを節約するために、コードの一部を省略しました。ここからわかるように、jQuery.fn は実際には jQuery のプロトタイプ オブジェクトであり、このプロトタイプ オブジェクトはこれに対するいくつかの操作を定義します。オブジェクト。この時点で少し混乱していると感じても、心配しないでください。アイデアを整理しましょう。jQuery は最初に init メソッドを定義し、次に init プロトタイプ オブジェクト プロトタイプに対する一連の操作メソッドを定義します。最後に、init メソッドのインスタンス オブジェクトが返されます。したがって、上記のプロセスは次のように簡略化できます (擬似コード表現):
var init = function(selector,context,root){ //... return this; } init.prototype = { length:0, each:function(callback){ //... }, splice:[].splice } jQuery = function(selector,context,root){ return new init(selector,context,root); }
そこで質問は、なぜ jQuery.fn のメソッドが init のプロトタイプではなく、jQuery のプロトタイプ オブジェクトで直接定義されているのかということです。
実は、これの目的はjQueryのクエリ効率を向上させるためで、initのプロトタイプオブジェクトに直接定義すると、クエリが実行されるたびにこのような巨大なプロトタイプオブジェクトがメモリ上に作成され、このオブジェクトが jQuery のプロトタイプで定義されている場合、このオブジェクトは初期化され、今後 $() が実行されるたびに常にメモリ内に存在します。必要なのは init 内のプロトタイプを指すことだけです。毎回同じオブジェクトを作成するのではなく、オブジェクトを作成します。
init 関数で返される this が正確に何であるかを見てみましょう。前回のブログで、関数内の this は実行時に常に呼び出し元を指すと述べました。では、init の呼び出し元は誰でしょうか。上記のコードでは呼び出し元が見つからないようですが、この時点で新しいオペレーターの動作メカニズムを深く理解する必要があるため、前回のブログの新しいオペレーターの説明を借りて、 の実行処理を実行します。 new init() は次のように分解されます:
new init(selector,context,root) = { var obj = {}; obj.__proto__ = init.prototype; init.call(obj,selector,context,root); return typeof result === 'obj'? result : obj; }
上記の分解プロセスからわかるように、JavaScript が new を通じてインスタンス オブジェクトを作成するとき、まず通常のオブジェクト obj を作成し、次に obj の内部属性 __proto__ を init のプロトタイプ オブジェクトにポイントするため、obj のプロトタイプはチェーンが変更され、ステップ 3 で call メソッドを使用して init() を呼び出すため、init の this はここで obj オブジェクトを参照します。
init() が実行されると、 は一致したすべての DOM オブジェクトを配列の形式でこのオブジェクトに格納して返します。つまり、obj オブジェクトが返され、新しい演算子は最終的にこの obj オブジェクトを次のように返します。新しいインスタンス オブジェクト。 そのため、 new オペレーターによって返されるインスタンス オブジェクトには 2 つの特性があります。1 つ目は、DOM クエリ結果セットが含まれること、2 つ目は、そのプロトタイプ チェーンが init のプロトタイプを継承し、init のプロトタイプが jQuery.fn オブジェクトを指すことです。インスタンス オブジェクト これらの操作方法も使用できます。
jQuery はクエリが実行されるたびに jQuery オブジェクトを作成し、同じアプリケーション内では、すべての jQuery オブジェクトが同じ jQuery プロトタイプ オブジェクトを共有します。したがって、jQuery オブジェクトには DOM クエリ結果セットが含まれるだけでなく、jQuery プロトタイプ オブジェクトの操作メソッドも継承されます。このようにして、クエリ後にメソッドを直接呼び出して、これらの DOM 要素を操作できます。これは jQuery のコア アーキテクチャ設計であり、シンプル、便利、実用的です。
上記の説明がまだ理解できない場合でも、心配しないでください。私は jQuery の設計思想に従って完全な小さなプロジェクト jDate を書きました。比較して理解することができます。 jDate プロジェクトは GitHub にアップロードされています: jDate をクリックすると完全なコードが表示されます。異なる意見がある場合は、お気軽に議論してください。
3 jQuery の欠陥
jQuery のコア アーキテクチャを分析すると、各 jQuery オブジェクトは同じ jQuery プロトタイプを共有しているにもかかわらず、クエリが実行されるたびに、jQuery がメモリ内に複雑な jQuery オブジェクトを構築することがわかります。しかし、jQuery のクエリ プロセスは、さまざまな一致する識別子とさまざまなブラウザの互換性を考慮する必要があります。したがって、DOM 上で単純な操作を行うだけの場合は、jQuery の代わりにネイティブ メソッド querySelector を使用することをお勧めします。ただし、ネイティブ メソッドを使用する場合は、さまざまなアプリケーション シナリオに合わせて互換性の作業を行う必要がある場合があります。 jQuery に依存しすぎないように、トレードオフを考慮してください。