J'aimerais comprendre la syntaxe du plugin jQuery

89

Le site jQuery répertorie la syntaxe de base du plugin pour jQuery comme suit:

(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 );

J'aimerais juste comprendre ce qui se passe là-bas du point de vue de Javascript, car il ne semble pas qu'il suive une syntaxe que j'ai vue JS faire auparavant. Voici donc ma liste de questions:

  1. Si vous remplacez la fonction ($) ... par une variable, dites "la_fonction", la syntaxe ressemble à ceci:

     (the_function)( jQuery );

    Qu'est-ce que "(jQuery);" Faire? Les parenthèses autour de la_fonction sont-elles vraiment nécessaires? Pourquoi sont-ils là? Y a-t-il un autre morceau de code que vous pouvez donner qui soit similaire?

  2. Cela commence par la fonction ($). Il s'agit donc de créer une fonction qui, pour autant que je sache, ne sera jamais exécutée, avec le paramètre $, qui est déjà défini? Que se passe-t-il ici?

Merci pour l'aide!

Ethan
la source

Réponses:

130
function(x){ 
    x...
}

est juste une fonction sans nom, qui prend un argument, "x", et fait des choses avec x.

Au lieu de «x», qui est un nom de variable courant, vous pouvez utiliser $, qui est un nom de variable moins courant, mais toujours légal.

function($){ 
    $...
}

Je vais le mettre entre parenthèses pour m'assurer qu'il est analysé comme une expression:

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

Pour appeler une fonction, vous mettez () après elle avec une liste d'arguments. Par exemple, si nous voulions appeler cette fonction en passant 3 pour la valeur de, $nous ferions ceci:

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

Juste pour les coups de pied, appelons cette fonction et passons jQuery en tant que variable:

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

Cela crée une nouvelle fonction qui prend un argument, puis appelle cette fonction, en passant jQuery comme valeur.

POURQUOI?

  • Parce qu'écrire jQuery chaque fois que vous voulez faire quelque chose avec jQuery est fastidieux.

POURQUOI NE PAS SEULEMENT ÉCRIRE $ = jQuery?

  • Parce que quelqu'un d'autre aurait pu définir $ comme signifiant autre chose. Cela garantit que toutes les autres significations de $ sont masquées par celle-ci.
Joël Spolsky
la source
20
C'est clair, mais il manque une élaboration sur la nécessité de guider l'analyseur dans l'analyse de la définition de fonction en tant qu'expression et non en tant qu'instruction . C'est à cela que servent les parenthèses supplémentaires .
Pointy
16
(function(){})()est connu comme un IIFE (expression de fonction immédiatement invoquée) . Que l'on sache que vous pouvez utiliser d' autres symboles pour forcer l'analyseur pour traiter la fonction comme une expression telle que +,!,-,~(et d' autres) comme ceci: !function($){}(jQuery). Et pour encore plus de plaisir, vous pouvez ~~+-!function($){}(jQuery):!
David Murdoch
(fonction ($, win, doc) {$ ....}) (jQuery, fenêtre, document); J'ajouterais ceci aussi ... Cela m'a aidé à mieux comprendre. dans cette paix de code, jQuery ---> $; et fenêtre ---> gagner; puis document ---> doc ... :) merci ...
Haranadh
J'ai fait face à un exemple de code qui à mon humble avis n'est pas couvert dans la liste ci-dessus: $ (function () {.....} (jQuery)); (Tiré d'ici: docs.microsoft.com/en-us/aspnet/core/mvc/models/… ). Ici, je ne comprends pas l'utilisation du $. Cela ne semble pas être un sélecteur jQuery $ (...) ou une syntaxe courte pour l'événement 'document ready', car la fonction ne renvoie rien. Je ne semble pas non plus être un préfixe pour traiter la fonction comme une expression, car elle est en dehors des accolades. De plus, l'appel de fonction est effectué À L'INTÉRIEUR des accolades, nous appelons donc déclaration.
sich
35

(function( $ ){

})( jQuery );

C'est une fonction anonyme auto-exécutable qui utilise $en argument pour que vous puissiez l'utiliser ( $) au lieu de l' jQueryintérieur de cette fonction et sans craindre d'entrer en conflit avec d'autres bibliothèques car dans d'autres bibliothèques a aussi $une signification particulière. Ce modèle est particulièrement utile lors de l'écriture de plugins jQuery.

Vous pouvez y écrire n'importe quel caractère au lieu de $:

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

})(jQuery);

Ici jrattrapera automatiquement jQuery spécifié à la fin (jQuery). Ou vous pouvez omettre complètement l'argument, mais vous devrez alors utiliser le jQuerymot-clé tout autour plutôt $que sans craindre une collision. Donc, $est enveloppé dans l'argument de raccourci afin que vous puissiez écrire $au lieu de jQuerytout autour de cette fonction.

Si vous regardez même le code source de jQuery, vous verrez que tout est encapsulé entre:

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

C'est comme on peut le voir aussi une fonction anonyme auto-exécutable avec des arguments. Un argument window(et undefined) est créé et mappé avec l' windowobjet global en bas (window). C'est un modèle populaire ces jours-ci et a peu de gain de vitesse car ici, windowil sera examiné à partir de l'argument plutôt que de l' windowobjet global qui est mappé ci-dessous.


C'est $.fnl'objet de jQuery où vous créez votre nouvelle fonction (qui est également un objet) ou le plugin lui-même afin que jQuery enveloppe votre plugin dans son $.fnobjet et le rend disponible.


Fait intéressant, j'avais répondu à une question similaire ici:

Syntaxe de la fonction de fermeture JavaScript / jQuery

Vous pouvez également consulter cet article pour en savoir plus sur les fonctions auto-exécutables que j'avais écrites:

Fonctions Javascript auto-exécutables

Sarfraz
la source
Donc, si j'avais un objet appelé mon_objet, et que je faisais ceci: (function (mo) {mo.doSomething ()}) (my_object), alors il exécuterait my_object.doSomething ()?
Ethan
3

La syntaxe de base du plugin vous permet d'utiliser $pour faire référence jQuerydans le corps de votre plugin, quel que soit l'identifiant $au moment où le plugin est chargé. Cela évite les conflits de noms avec d'autres bibliothèques, notamment Prototype.

La syntaxe définit une fonction qui accepte un paramètre connu sous le nom de $sorte que vous puissiez y faire référence comme $dans le corps de la fonction, puis invoque immédiatement cette fonction, en la plaçant jQuerycomme argument.

Cela permet également de ne pas polluer l'espace de noms global (donc déclarer var myvar = 123;dans le corps de votre plugin ne définira pas soudainement window.myvar), mais le principal objectif ostensible est de vous permettre d'utiliser $$peut avoir été redéfini depuis.

Steven
la source
3

Vous avez affaire à une fonction anonyme auto-invoquée ici. C'est comme la "meilleure pratique" pour envelopper un plugin jQuery dans une telle fonction pour s'assurer que le $signe est lié à l' jQueryobjet.

Exemple:

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

Cela alerterait une BARfois mis dans un <script>bloc. Le paramètre BARest passé à la fonction qui s'appelle elle-même.

Le même principe se produit dans votre code, l' jQueryobjet est passé à la fonction, donc $fera référence à l'objet jQuery à coup sûr.

jAndy
la source
1
Je comprends tout cela. Ce que je veux savoir, c'est pourquoi / comment la syntaxe entre crochets fonctionne pour créer une fonction auto-exécutable? Est-ce juste une caractéristique de la langue? Comment ça marche?
chair
2

Le jQuery à la fin passe lui-même (jQuery) à la fonction, afin que vous puissiez utiliser le symbole $ dans votre plugin. Tu pourrais aussi faire

(function(foo){

  foo.fn.myPlugin = function() {


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


    });

  };
})( jQuery );
harpax
la source
2

Pour trouver une explication claire de cela et d'autres astuces javascript modernes et pratiques courantes, je vous recommande de lire Javascript Garden.

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

C'est particulièrement utile, car beaucoup de ces modèles sont largement utilisés dans de nombreuses bibliothèques mais pas vraiment expliqués.

OlliM
la source
2

Les autres réponses ici sont excellentes, mais il y a un point important qui n'a pas été abordé. Vous dites:

Il s'agit donc de créer une fonction qui, pour autant que je sache, ne sera jamais exécutée, avec le paramètre $, qui est déjà défini?

Il n'y a aucune garantie que la variable globale $est disponible . Par défaut, jQuery crée deux variables dans la portée globale: $et jQuery(où les deux sont des alias pour le même objet). Cependant, jQuery peut également être exécuté en mode noConflict :

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

Lorsque vous appelez jQuery.noConflict(), la variable globale $est redéfinie sur ce qu'elle était avant l'inclusion de la bibliothèque jQuery. Cela permet à jQuery d'être utilisé avec d'autres bibliothèques Javascript qui utilisent également$ comme variable globale.

Si vous avez écrit un plugin qui reposait sur le fait d' $être un alias pour jQuery, alors votre plugin ne fonctionnerait pas pour les utilisateurs fonctionnant en mode noConflict.

Comme d'autres l'ont déjà expliqué, le code que vous avez publié crée une fonction anonyme qui est appelée immédiatement. La variable globale jQueryest ensuite transmise à cette fonction anonyme, qui est aliasée en toute sécurité en tant que variable locale$ dans la fonction.

Kip
la source