Que fait (function ($) {}) (jQuery); signifier?

299

Je commence tout juste à écrire des plugins jQuery. J'ai écrit trois petits plugins mais j'ai simplement copié la ligne dans tous mes plugins sans vraiment savoir ce que cela signifie. Quelqu'un peut-il m'en dire un peu plus à ce sujet? Peut-être qu'une explication vous sera utile un jour lors de l'écriture d'un framework :)

Qu'est-ce que cela fait? (Je sais que cela étend jQuery d'une manière ou d'une autre, mais y a-t-il autre chose intéressant à savoir à ce sujet)

(function($) {

})(jQuery);

Quelle est la différence entre les deux façons suivantes d'écrire un plugin:

Type 1:

(function($) {
    $.fn.jPluginName = {

        },

        $.fn.jPluginName.defaults = {

        }
})(jQuery);

Type 2:

(function($) {
    $.jPluginName = {

        }
})(jQuery);

Type 3:

(function($){

    //Attach this new method to jQuery
    $.fn.extend({ 

        var defaults = {  
        }  

        var options =  $.extend(defaults, options);  

        //This is where you write your plugin's name
        pluginname: function() {

            //Iterate over the current set of matched elements
            return this.each(function() {

                //code to be inserted here

            });
        }
    }); 
})(jQuery);

Je pourrais être loin d'ici et peut-être tous signifient la même chose. Je suis confus. Dans certains cas, cela ne semble pas fonctionner dans un plugin que j'écrivais en utilisant le Type 1. Jusqu'à présent, le Type 3 me semble le plus élégant mais j'aimerais aussi connaître les autres.

Légende
la source
22
Il est temps de se coucher ici, mais juste pour commencer, (function($) { })(jQuery);le code $est jQueryencapsulé de sorte qu'il se trouve à l' intérieur de cette fermeture, même s'il $signifie autre chose en dehors, généralement à la suite, $.noConflict()par exemple. Cela garantit que votre plugin fonctionne, que ce soit ou non $ === jQuery :)
Nick Craver
3
À propos de (function($) { })(jQuery)vous, vous avez dit: "Je sais que cela étend jQuery en quelque sorte [...]". De toute évidence, vous ne savez pas , car votre déclaration est fausse à 100%. Au fait, cela peut être trompeur pour les futurs lecteurs. Jetez un œil à ceci: stackoverflow.com/a/32550649/1636522 .
le
S'étendant sur les commentaires de @ NickCraver, jquery-ui-1.7.2.custom.min.js utilise par exemple: jQuery.ui || (fonction (c) {var i = c.fn.remove, d = c.browser. mozilla ........}) (jQuery) ;. Je sais que c'est une ancienne version de jQuery UI avec du code obsolète, mais le but est de montrer comment dans ce cas, ils utilisent "c" au lieu de "$".
Jaime Montoya

Réponses:

234

Tout d'abord, un bloc de code qui ressemble à (function(){})()est simplement une fonction qui est exécutée sur place. Décomposons-le un peu.

1. (
2.    function(){}
3. )
4. ()

La ligne 2 est une fonction simple, entourée de parenthèses pour indiquer au runtime de renvoyer la fonction à la portée parent, une fois qu'elle est retournée, la fonction est exécutée à l'aide de la ligne 4, peut-être que la lecture de ces étapes vous aidera

1. function(){ .. }
2. (1)
3. 2()

Vous pouvez voir que 1 est la déclaration, 2 renvoie la fonction et 3 exécute simplement la fonction.

Un exemple de la façon dont il serait utilisé.

(function(doc){

   doc.location = '/';

})(document);//This is passed into the function above

Quant aux autres questions sur les plugins:

Type 1: Ce n'est pas vraiment un plugin, c'est un objet passé en tant que fonction, car les plugins ont tendance à être des fonctions.

Type 2: Ce n'est pas encore un plugin car il ne prolonge pas l' $.fnobjet. C'est juste une extension du noyau jQuery, bien que le résultat soit le même. C'est le cas si vous souhaitez ajouter des fonctions de déplacement telles que toArray et ainsi de suite.

Type 3: C'est la meilleure méthode pour ajouter un plugin, le prototype étendu de jQuery prend un objet contenant le nom et la fonction de votre plugin et l'ajoute à la bibliothèque de plugins pour vous.

RobertPitt
la source
2
si vous lisez la question d'origine, l'OP spécifie 3 méthodes d'écriture des fermetures, il a nommé ces méthodes de type {1,2,3}, je me réfère farouchement aux zones de la question avec une réponse ..
RobertPitt
1
(function () {}) signifie renvoie la fonction interne? Que signifie exactement le "()"?
Jaskey
J'aime le premier exemple mais le second utilisant des références de numéro de ligne (qui n'est pas une fonction js) n'est pas clair.
Samy Bencherif
1
Cela s'appelle l'expression de fonction immédiatement invoquée (IIFE): benalman.com/news/2010/11/…
Andres Rojas
1
J'ai le plus de problèmes à comprendre la parenthèse externe de ( function(){} ): qu'est-ce que c'est exactement? Puis-je non seulement écrire function(){}()?
TMOTTM
127

Au niveau le plus élémentaire, quelque chose de la forme (function(){...})()est un littéral de fonction qui est exécuté immédiatement. Cela signifie que vous avez défini une fonction et que vous l'appelez immédiatement.

Ce formulaire est utile pour cacher et encapsuler des informations car tout ce que vous définissez à l'intérieur de cette fonction reste local à cette fonction et inaccessible du monde extérieur (sauf si vous l'exposez spécifiquement - généralement via un objet renvoyé littéral).

Une variation de cette forme de base est ce que vous voyez dans les plugins jQuery (ou dans ce modèle de module en général). Par conséquent:

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

Ce qui signifie que vous passez une référence à l' jQueryobjet réel , mais il est connu comme étant $dans le cadre du littéral de la fonction.

Le type 1 n'est pas vraiment un plugin. Vous affectez simplement un objet littéral à jQuery.fn. En règle générale, vous affectez une fonction jQuery.fncar les plugins ne sont généralement que des fonctions.

Le type 2 est similaire au type 1; vous ne créez pas vraiment de plugin ici. Vous ajoutez simplement un objet littéral à jQuery.fn.

Le type 3 est un plugin, mais ce n'est pas le meilleur ou le plus simple pour en créer un.

Pour en savoir plus à ce sujet, jetez un œil à cette question et réponse similaire . De plus, cette page donne quelques détails sur la création de plugins.

Vivin Paliath
la source
1
Je ne sais pas comment Type 3 étend le noyau. C'est un moyen parfaitement valide de créer un plugin puisque vous étendez le prototype. Quoique un peu inutile.
tbranyen
1
Mon mauvais - j'aurais dû être plus clair. J'étais pressé et vous avez raison.
Vivin Paliath
32

Un peu d'aide:

// an anonymous function
  
(function () { console.log('allo') });

// a self invoked anonymous function

(function () { console.log('allo') })();
  
// a self invoked anonymous function with a parameter called "$"
  
var jQuery = 'I\'m not jQuery.';

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

feuille
la source
21

Juste un petit ajout à l'explication

Cette structure (function() {})();est appelée IIFE (Immediateely Invoked Function Expression), elle sera exécutée immédiatement, lorsque l'interpréteur atteindra cette ligne. Ainsi, lorsque vous écrivez ces lignes:

(function($) {
  // do something
})(jQuery);

cela signifie que l'interpréteur invoquera immédiatement la fonction et passera jQuerycomme paramètre, qui sera utilisé à l'intérieur de la fonction comme $.

Suicide commercial
la source
12

En fait, cet exemple m'a aidé à comprendre ce que cela (function($) {})(jQuery);signifie.

Considère ceci:

// Clousure declaration (aka anonymous function)
var f = function(x) { return x*x; };
// And use of it
console.log( f(2) ); // Gives: 4

// An inline version (immediately invoked)
console.log( (function(x) { return x*x; })(2) ); // Gives: 4

Et maintenant, considérez ceci:

  • jQuery est une variable contenant un objet jQuery.
  • $est un nom de variable comme un autre ( a, $b, a$betc.) et il n'a pas de signification particulière comme en PHP.

Sachant que nous pouvons revoir notre exemple:

var $f = function($) { return $*$; };
var jQuery = 2;
console.log( $f(jQuery) ); // Gives: 4

// An inline version (immediately invoked)
console.log( (function($) { return $*$; })(jQuery) ); // Gives: 4
Krzysztof Przygoda
la source
Pour moi, c'est la meilleure réponse. clair et si simple
Saleh
11

Type 3, afin de travailler devrait ressembler à ceci:

(function($){
    //Attach this new method to jQuery
    $.fn.extend({     
        //This is where you write your plugin's name
        'pluginname': function(_options) {
            // Put defaults inline, no need for another variable...
            var options =  $.extend({
                'defaults': "go here..."
            }, _options);

            //Iterate over the current set of matched elements
            return this.each(function() {

                //code to be inserted here

            });
        }
    }); 
})(jQuery);

Je ne sais pas pourquoi quelqu'un utiliserait étendre sur simplement définir directement la propriété dans le prototype jQuery, il fait exactement la même chose que dans plus d'opérations et plus d'encombrement.

tbranyen
la source