Ich möchte die Syntax des jQuery-Plugins verstehen

89

Die jQuery-Site listet die grundlegende Plugin-Syntax für jQuery wie folgt auf:

(function( $ ){    
  $.fn.myPlugin = function() {      
    // there's no need to do $(this) because
    // "this" is already a jquery object

    // $(this) would be the same as $($('#element'));

    this.fadeIn('normal', function(){    
      // the this keyword is a DOM element    
    });    
  };
})( jQuery );

Ich möchte nur verstehen, was dort aus der Sicht von Javascript vor sich geht, da es nicht so aussieht, als ob es einer Syntax folgt, die JS zuvor gesehen hat. Hier ist meine Liste mit Fragen:

  1. Wenn Sie die Funktion ($) ... durch eine Variable ersetzen, sagen Sie "the_function", sieht die Syntax folgendermaßen aus:

     (the_function)( jQuery );

    Was ist "(jQuery);" tun? Sind die Klammern um die Funktion wirklich notwendig? Warum sind die hier? Gibt es einen anderen Code, den Sie geben können, der ähnlich ist?

  2. Es beginnt mit der Funktion ($). Es wird also eine Funktion erstellt, die, soweit ich das beurteilen kann, niemals ausgeführt wird, mit dem Parameter $, der bereits definiert ist? Was ist da los?

Danke für die Hilfe!

Ethan
quelle

Antworten:

130
function(x){ 
    x...
}

ist nur eine Funktion ohne Namen, die ein Argument "x" annimmt und Dinge mit x macht.

Anstelle von 'x', einem gebräuchlichen Variablennamen, können Sie $ verwenden, einen weniger gebräuchlichen Variablennamen, der jedoch weiterhin zulässig ist.

function($){ 
    $...
}

Ich werde es in Klammern setzen, um sicherzustellen, dass es als Ausdruck analysiert wird:

(function($){
    $....
})

Um eine Funktion aufzurufen, setzen Sie () mit einer Liste von Argumenten nach. Wenn wir zum Beispiel diese Funktion aufrufen $möchten, indem wir 3 für den Wert von übergeben , würden wir Folgendes tun:

(function($){
    $...
})(3);

Rufen wir diese Funktion nur zum Spaß auf und übergeben Sie jQuery als Variable:

(function($){
     $....
})(jQuery);

Dadurch wird eine neue Funktion erstellt, die ein Argument verwendet und diese Funktion dann aufruft und jQuery als Wert übergibt.

WARUM?

  • Weil das Schreiben von jQuery jedes Mal, wenn Sie etwas mit jQuery tun möchten, mühsam ist.

WARUM NICHT NUR SCHREIBEN $ = jQuery?

  • Weil jemand anderes $ definiert haben könnte, um etwas anderes zu bedeuten. Dies garantiert, dass alle anderen Bedeutungen von $ von dieser beschattet werden.
Joel Spolsky
quelle
20
Es ist klar, aber es fehlt eine Ausarbeitung der Notwendigkeit, den Parser dazu zu führen, die Funktionsdefinition als Ausdruck und nicht als Anweisung zu analysieren . Dafür stehen die zusätzlichen Klammern.
Pointy
16
(function(){})()ist als IIFE (Sofort aufgerufener Funktionsausdruck) bekannt . Lassen Sie uns wissen, dass Sie andere Symbole verwenden können, um den Parser zu zwingen, die Funktion als Ausdruck wie +,!,-,~(und andere) wie folgt zu behandeln : !function($){}(jQuery). Und für noch mehr Spaß können Sie : ~~+-!function($){}(jQuery)!
David Murdoch
(Funktion ($, win, doc) {$ ....}) (jQuery, Fenster, Dokument); Ich würde das auch hinzufügen ... Es hat mir geholfen, besser zu verstehen. in dieser Ruhe des Codes jQuery ---> $; und Fenster ---> gewinnen; dann dokument ---> doc ... :) danke ...
Haranadh
Ich habe ein Codebeispiel gesehen, das meiner Meinung nach in der obigen Liste nicht behandelt wird: $ (function () {.....} (jQuery)); (Von hier aus entnommen: docs.microsoft.com/en-us/aspnet/core/mvc/models/… ). Hier verstehe ich die Verwendung des $ nicht. Es scheint weder ein jQuery-Selektor $ (...) noch eine kurze Syntax für das Ereignis 'document ready' zu sein, da die Funktion nichts zurückgibt. Ich scheine auch kein Präfix zu sein, um die Funktion als Ausdruck zu behandeln, da sie außerhalb der geschweiften Klammern liegt. Außerdem wird der Funktionsaufruf IN den geschweiften Klammern ausgeführt, sodass wir die Deklaration aufrufen.
sich
35

(function( $ ){

})( jQuery );

Dies ist eine selbstausführende anonyme Funktion, die $in Argumenten verwendet wird, damit Sie sie ( $) anstelle jQuerydieser Funktion verwenden können, ohne befürchten zu müssen, mit anderen Bibliotheken in Konflikt zu geraten, da auch in anderen Bibliotheken $eine besondere Bedeutung hat. Dieses Muster ist besonders nützlich, wenn Sie jQuery-Plugins schreiben.

Sie können dort jedes Zeichen schreiben, anstatt $auch:

(function(j){
  // can do something like 
  j.fn.function_name = function(x){};

})(jQuery);

Hier jwird automatisch die am Ende angegebene jQuery abgerufen (jQuery). Oder Sie können das Argument komplett weglassen, aber dann müssen Sie das jQuerySchlüsselwort rundum verwenden, anstatt $immer noch keine Angst vor einer Kollision zu haben. Wird $also in das Argument für Kurzschrift eingewickelt, damit Sie innerhalb dieser Funktion schreiben können, $anstatt jQueryringsum.

Wenn Sie sich sogar den Quellcode von jQuery ansehen, werden Sie feststellen, dass alles dazwischen eingeschlossen ist:

(function( window, undefined ) {
  // jQuery code
})(window);

Das ist, wie zu sehen ist, auch eine selbstausführende anonyme Funktion mit Argumenten. Ein window(und undefined) Argument wird erstellt und dem globalen windowObjekt unten zugeordnet (window). Dies ist heutzutage ein beliebtes Muster und hat nur einen geringen Geschwindigkeitsgewinn, da hier windoweher das Argument als windowdas unten abgebildete globale Objekt untersucht wird.


Das $.fnist Aufgabe der jQuery , wo Sie Ihre neue Funktion erstellen (die auch ein Objekt ist) oder das Plugin selbst , so dass jQuery hüllt dein Plugin in seinem $.fnObjekt und zur Verfügung stellen.


Interessanterweise hatte ich hier eine ähnliche Frage beantwortet:

Syntax der JavaScript / jQuery-Schließfunktion

Sie können auch diesen Artikel lesen, um mehr über selbstausführende Funktionen zu erfahren, die ich geschrieben habe:

Javascript Selbstausführende Funktionen

Sarfraz
quelle
Wenn ich also ein Objekt namens my_object hätte und dies tun würde: (function (mo) {mo.doSomething ()}) (my_object), würde es my_object.doSomething () ausführen?
Ethan
3

Mit der grundlegenden Plugin-Syntax können Sie unabhängig von der Identität des Plugins auf den Inhalt Ihres Plugins $verweisenjQuery$ zum Zeitpunkt des Ladens des Plugins. Dies verhindert Namenskonflikte mit anderen Bibliotheken, insbesondere Prototype.

Die Syntax definiert eine Funktion, die einen so genannten Parameter akzeptiert, $sodass Sie ihn wie $im Funktionskörper referenzieren können , und diese Funktion dann sofort aufruft und setztjQuery als Argument eingibt.

Dies hilft auch dabei, den globalen Namespace nicht zu verschmutzen (so dass das Deklarieren var myvar = 123;in Ihrem Plugin-Body nicht plötzlich definiert wird window.myvar), aber der Hauptzweck besteht darin, Ihnen zu ermöglichen, zu verwenden, $wo $möglicherweise seitdem neu definiert wurde.

Steven
quelle
3

Sie haben es dort mit einer selbstaufrufenden anonymen Funktion zu tun. Es ist wie "Best Practice", ein jQuery-Plugin in eine solche Funktion einzuschließen, um sicherzustellen, dass das $Zeichen an das jQueryObjekt gebunden ist .

Beispiel:

(function(foo) {
    alert(foo);
}('BAR'));

Dies würde alarmieren, BARwenn es in einen <script>Block gelegt wird. Der ParameterBAR wird an die Funktion übergeben, die sich selbst aufruft.

Das gleiche Prinzip geschieht in Ihrem Code, das jQueryObjekt wird an die Funktion übergeben, $verweist also sicher auf das jQuery-Objekt.

jAndy
quelle
1
Ich verstehe das alles. Ich möchte wissen, warum / wie die Klammer-Syntax funktioniert, um eine selbstausführende Funktion zu erstellen. Ist das nur ein Merkmal der Sprache? Wie funktioniert es?
Fleisch
2

Die jQuery am Ende übergibt sich (jQuery) an die Funktion, sodass Sie das $ -Symbol in Ihrem Plugin verwenden können. Sie könnten es auch tun

(function(foo){

  foo.fn.myPlugin = function() {


    this.fadeIn('normal', function(){


    });

  };
})( jQuery );
Harpax
quelle
2

Um eine klare Erklärung für diese und andere moderne Javascript-Tricks und gängige Praktiken zu finden, empfehle ich, Javascript Garden zu lesen.

http://bonsaiden.github.com/JavaScript-Garden/

Dies ist besonders nützlich, da viele dieser Muster in vielen Bibliotheken weit verbreitet sind, aber nicht wirklich erklärt werden.

OlliM
quelle
2

Die anderen Antworten hier sind großartig, aber es gibt einen wichtigen Punkt, der nicht angesprochen wurde. Du sagst:

Es wird also eine Funktion erstellt, die, soweit ich das beurteilen kann, niemals ausgeführt wird, mit dem Parameter $, der bereits definiert ist?

Es gibt keine Garantie dafür, dass die globale Variable $verfügbar ist . Standardmäßig erstellt jQuery zwei Variablen im globalen Bereich: $und jQuery(wobei die beiden Aliase für dasselbe Objekt sind). Allerdings jQuery kann auch in noConflict Modus ausgeführt werden :

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
  jQuery.noConflict();
</script>

Wenn Sie aufrufen jQuery.noConflict(), wird die globale Variable $auf den Wert zurückgesetzt, der vor der Aufnahme der jQuery-Bibliothek vorhanden war. Dadurch kann jQuery mit anderen Javascript-Bibliotheken verwendet werden, die auch $als globale Variable verwendet werden.

Wenn Sie ein Plugin geschrieben haben, $das als Alias ​​für jQuery fungiert, funktioniert Ihr Plugin nicht für Benutzer, die im noConflict-Modus ausgeführt werden.

Wie andere bereits erklärt haben, erstellt der von Ihnen veröffentlichte Code eine anonyme Funktion, die sofort aufgerufen wird. Die globale Variable jQuerywird dann an diese anonyme Funktion übergeben, die sicher als lokale Variable $innerhalb der Funktion aliasiert ist .

Pennen
quelle