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('div') と同等です。 このメソッドが実行することは 1 つだけであることがわかります。 jQuery.fn.init () 関数インスタンス オブジェクトを返すには、jQuery.fn.init とは何でしょうか。次のコードを見てみましょう:
init = jQuery.fn.init = function( selector, context, root ) { //... return this; } init.prototype = jQuery.fn;
jQuery.fn.init と init は同じメソッドを参照します。このメソッドは、セレクターが条件を満たす DOM 要素をクエリして返しますが、返される内容は次のとおりです。後で分析します。まず次の文を見てみましょう。
init.prototype = jQuery.fn;
この文は何を意味しますか?この文では、init メソッドのプロトタイプ オブジェクトが jQuery.fn オブジェクトを指すようにしていますが、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 のプロトタイプで定義されている場合、このオブジェクトは 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物件以數組的方式儲存到this物件中並傳回,也就是傳回了obj對象,而new運算子最終也會將這個obj 對象傳回以作為新的實例物件。所以new運算子傳回的這個實例物件有兩個特點:一是包含了DOM查詢結果集,二是其原型鏈繼承了init的prototype,而init 的prototype 又指向了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做一些簡單的操作,建議使用原生方法querySelector 替代jQuery,不過在使用原生方法時,對於不同的應用場景你可能要做一些兼容性的工作,你要學會取捨,不要過度依賴jQuery!
以上就是本文的全部內容,希望對大家學習jquery有所啟發,更多相關教程請訪問jQuery視頻教程!