jQuery ist nicht jedem fremd, daher werde ich hier nicht viel darüber sagen, was es ist und was es tut. Der Zweck dieses Artikels besteht darin, den Kern von jQuery anhand einer einfachen Analyse des Architekturdesigns zu diskutieren und wie jQuery erweiterte Funktionen in JavaScript nutzt, um eine so großartige JavaScript-Bibliothek aufzubauen.
1 Erste Einführung in jQuery
Aus Sicht der Kernfunktion führt jQuery nur eine einfache und gewöhnliche Sache aus: Abfragen. Seine Syntax ist so prägnant und klar, dass viele Menschen jQuery bereits verwendet haben, ohne zu wissen, was Javascript ist. Um es mit einem Wort zu beschreiben: Einfachheit und Einfachheit. Aus gestalterischer Sicht können wir die von jQuery bereitgestellten Methoden in zwei Hauptkategorien einteilen: statische Methoden und Instanzmethoden. Statische Methoden sind Methoden, auf die direkt über $ zugegriffen wird. Diese Methoden arbeiten im Allgemeinen nicht mit DOM-Elementen, bieten jedoch einige gängige Tools wie Ajax-Anfragen und einige gängige Operationen für Zeichenfolgen. Darüber hinaus bietet jQuery auch einen eigenen Erweiterungsmechanismus Schreiben Sie die benötigten Komponenten über die Extend-Methode. Die Instanzmethode unterscheidet sich von der statischen Methode. Sie wird verwendet, um die von jQuery abgefragten DOM-Elemente zu bearbeiten. Dieses Objekt speichert alle abgefragten DOM-Elemente in einer Array-Methode Dies Die Prototypenkette des Objekts implementiert Methoden zum Betreiben dieser DOMs. Beispielsweise wird die Methode every() zum Durchlaufen jedes DOM-Elements verwendet. Möglicherweise ist Ihnen aufgefallen, dass ich gerade gesagt habe, dass dieses Objekt „als Array“ gespeichert wird, das heißt, das von jQuery erstellte Objekt ist kein Array. Was genau ist dieses Objekt also? Tatsächlich ist dieses Objekt der Kern von jQuery und wird auch als „jQuery-Objekt“ bezeichnet. Daher liegt der Schwerpunkt dieses Artikels auf der Analyse und Diskussion von jQuery-Objekten.
2 jQuery-Objekt
Im Allgemeinen verwenden wir jQuery wie folgt:
$('div').each(function(index){ //this ...});
$('div ' ) gibt nach der Ausführung ein jQuery-Objekt zurück. Die Methode every() durchläuft die DOM-Elemente in diesem Objekt. Schauen wir uns zunächst den Ausführungsprozess von $('div') an (der Quellcode dieses Artikels stammt aus jQuery 3.0):
jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); }
Diese Methode ist die Eingabemethode von $('div'). $ ist die Abkürzung von jQuery, die jQuery('div') entspricht dass diese Methode nur das Instanzobjekt der Funktion jQuery.fn.init() zurückgibt. Schauen wir uns also den folgenden Code an:
init = jQuery.fn.init = = jQuery.fn;
jQuery.fn.init und init beziehen sich auf dieselbe Methode. Diese Methode fragt die qualifizierten DOM-Elemente basierend auf dem Selektor ab und gibt sie zurück. Was ist das? Wir werden es später analysieren. Schauen wir uns zunächst den folgenden Satz an:
init.prototype = jQuery.fn;
Was bedeutet dieser Satz? Objekt, was zum Teufel ist jQuery.fn? Schauen wir uns den Code weiter an:
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 };
Aus Platzgründen habe ich einen Teil des Codes weggelassen. Wie hier zu sehen ist, handelt es sich bei jQuery.fn tatsächlich um das Prototypobjekt von jQuery. Dieses Prototypobjekt definiert einige Methoden für die Bearbeitung dieses Objekts. Wenn Sie an dieser Stelle etwas verwirrt sind, machen Sie sich keine Sorgen, lassen Sie uns die Ideen klären: jQuery definiert zunächst eine Init-Methode und definiert dann eine Reihe von Operationsmethoden für den Init-Prototyp-Objektprototyp. Abschließend wird das Instanzobjekt der Init-Methode zurückgegeben. Der obige Prozess kann also wie folgt vereinfacht werden (Pseudocode-Darstellung):
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); }
Dann stellt sich die Frage, warum die Methoden in jQuery.fn nicht direkt auf dem Prototyp von init definiert sind ? Um es auf dem Prototypobjekt von jQuery zu definieren?
Der eigentliche Zweck besteht darin, die Abfrageeffizienz von jQuery zu verbessern. Wenn es direkt im Prototypobjekt von init definiert wird, wird bei jeder Ausführung einer Abfrage ein so großes Prototypobjekt erstellt den Speicher, und wenn dieses Objekt im jQuery-Prototyp definiert ist, wird dieses Objekt beim Laden von jQuery initialisiert und ist immer im Speicher vorhanden. Jedes Mal, wenn $() in der Zukunft ausgeführt wird, müssen Sie nur auf den Prototyp in init verweisen dieses Objekt, anstatt jedes Mal das gleiche Objekt zu erstellen.
Schauen wir uns an, was in der Init-Funktion zurückgegeben wird. Ich habe in meinem vorherigen Blog gesagt, dass dies in der Funktion während der Laufzeit immer auf den Aufrufer verweist. Es scheint, dass der Aufrufer im obigen Code nicht zu finden ist. Zu diesem Zeitpunkt müssen wir den Funktionsmechanismus des neuen Operators genau verstehen und die Beschreibung des neuen Operators in meinem vorherigen Blog ausführen new init(). Es ist wie folgt aufgeteilt:
new init(selector,context,root) = { var obj = {}; obj.__proto__ = init.prototype; init.call(obj,selector,context,root); return typeof result === 'obj'? result : obj; }
Wie aus dem obigen Zerlegungsprozess ersichtlich ist, erstellt JavaScript beim Erstellen eines Instanzobjekts über new zunächst ein gemeinsames Objekt obj und verweist dann das interne Attribut __proto__ von obj auf das Prototypobjekt von init, also obj Das Die Prototypenkette wird geändert und Schritt 3 verwendet die Call-Methode zum Aufrufen von init(), sodass sich dies in init hier auf das obj-Objekt bezieht. Nachdem
init() ausgeführt wurde, speichert alle übereinstimmenden DOM-Objekte in Form eines Arrays in diesem Objekt und gibt es zurück, d. h. das obj-Objekt wird zurückgegeben, und der neue Operator wird zurückgegeben Schließlich wird dieses obj-Objekt als neues Instanzobjekt zurückgegeben. Das vom neuen Operator zurückgegebene Instanzobjekt weist also zwei Merkmale auf: Erstens enthält es die DOM-Abfrageergebnismenge, und zweitens erbt seine Prototypkette den Prototyp von init, und der Prototyp von init zeigt auf das jQuery.fn-Objekt Daher verfügen auch Instanzobjekte über diese Operationsmethoden.
jQuery erstellt jedes Mal ein jQuery-Objekt, wenn eine Abfrage ausgeführt wird, und in derselben Anwendung verwenden alle jQuery-Objekte dasselbe jQuery-Prototypobjekt. Daher enthält das jQuery-Objekt nicht nur die DOM-Abfrageergebnismenge, sondern erbt auch die Operationsmethoden für das jQuery-Prototypobjekt. Auf diese Weise können Sie nach der Abfrage direkt Methoden aufrufen, um diese DOM-Elemente zu bearbeiten. Dies ist das Kernarchitekturdesign von jQuery, einfach, bequem und praktisch!
Wenn Sie die obige Erklärung immer noch nicht verstehen, machen Sie sich keine Sorgen, ich habe ein komplettes kleines Projekt jDate gemäß den Designideen von jQuery geschrieben, das Sie vergleichen und verstehen können! Das jDate-Projekt wurde auf GitHub hochgeladen. Sie können hier klicken, um den vollständigen Code anzuzeigen: jDate.
3 Mängel von jQuery
Durch die Analyse der Kernarchitektur von jQuery werden wir feststellen, dass jQuery jedes Mal, wenn eine Abfrage ausgeführt wird, ein komplexes jQuery-Objekt im Speicher erstellen muss Obwohl jedes jQuery-Objekt denselben jQuery-Prototyp verwendet, ist der Abfrageprozess von jQuery weitaus komplizierter als Sie denken. Er muss verschiedene übereinstimmende Bezeichner und die Kompatibilität verschiedener Browser berücksichtigen. Wenn Sie daher nur einige einfache Vorgänge im DOM ausführen, wird empfohlen, die native Methode querySelector anstelle von jQuery zu verwenden. Bei Verwendung der nativen Methode müssen Sie jedoch möglicherweise einige Kompatibilitätsarbeiten für verschiedene Anwendungsszenarien durchführen Kompromisse eingehen und es nicht übertreiben. Hängt von jQuery ab!