Cosa fa (funzione ($) {}) (jQuery); significare?


299

Ho appena iniziato a scrivere plugin jQuery. Ho scritto tre piccoli plugin, ma ho semplicemente copiato la linea in tutti i miei plugin senza sapere cosa significhi. Qualcuno può dirmi qualcosa in più su questi? Forse una spiegazione tornerà utile un giorno quando si scrive un framework :)

Cosa fa questo? (So ​​che estende jQuery in qualche modo, ma c'è qualcos'altro di interessante da sapere su questo)

(function($) {

})(jQuery);

Qual è la differenza tra i seguenti due modi di scrivere un plugin:

Tipo 1:

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

        },

        $.fn.jPluginName.defaults = {

        }
})(jQuery);

Tipo 2:

(function($) {
    $.jPluginName = {

        }
})(jQuery);

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

Potrei essere lontano e forse significare tutti la stessa cosa. Sono confuso. In alcuni casi, questo non sembra funzionare in un plugin che stavo scrivendo usando il Tipo 1. Finora, il Tipo 3 mi sembra il più elegante, ma mi piacerebbe sapere anche degli altri.


22
È ora di andare a letto qui, ma solo per cominciare, (function($) { })(jQuery);racchiude il codice in modo che $sia jQueryall'interno di quella chiusura, anche se $significa qualcos'altro al di fuori di esso, di solito come risultato, $.noConflict()ad esempio. Questo assicura che il tuo plug-in funzioni, anche se $ === jQuery :)
Nick Craver

3
Chi (function($) { })(jQuery)hai detto: "So che estende jQuery in qualche modo [...]". Chiaramente non lo sai perché la tua affermazione è falsa al 100%. A proposito, può essere fuorviante per i futuri lettori. Dai un'occhiata a questo: stackoverflow.com/a/32550649/1636522 .
foglia

Estendendo i commenti di @ NickCraver, jquery-ui-1.7.2.custom.min.js lo usa ad esempio: jQuery.ui || (function (c) {var i = c.fn.remove, d = c.browser. mozilla ........}) (jQuery) ;. So che è una vecchia versione dell'interfaccia utente di jQuery con codice obsoleto, ma il punto è mostrare come, in tal caso, utilizzano "c" anziché "$".
Jaime Montoya,

Risposte:


234

In primo luogo, un blocco di codice che assomiglia (function(){})()è semplicemente una funzione che viene eseguita sul posto. Analizziamolo un po '.

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

La riga 2 è una funzione semplice, racchiusa tra parentesi per indicare al runtime di restituire la funzione all'ambito padre, una volta restituita la funzione viene eseguita utilizzando la riga 4, forse leggere questi passaggi può essere d'aiuto

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

Puoi vedere che 1 è la dichiarazione, 2 sta restituendo la funzione e 3 sta semplicemente eseguendo la funzione.

Un esempio di come sarebbe usato.

(function(doc){

   doc.location = '/';

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

Per quanto riguarda le altre domande sui plugin:

Tipo 1: questo non è in realtà un plugin, è un oggetto passato come una funzione, poiché i plugin tendono ad essere funzioni.

Tipo 2: questo non è ancora un plug-in in quanto non estende l' $.fnoggetto. È solo un'estensione del core jQuery, sebbene il risultato sia lo stesso. Questo è se si desidera aggiungere funzioni di movimento come Array e così via.

Tipo 3: questo è il metodo migliore per aggiungere un plug-in, il prototipo esteso di jQuery prende un oggetto che contiene il nome e la funzione del plug-in e lo aggiunge alla libreria dei plug-in.


2
se leggi la domanda originale, l'OP specifica 3 metodi di scrittura delle chiusure, ha chiamato quei metodi di tipo {1,2,3}, mi riferisco magistralmente alle aree all'interno della domanda con una risposta ..
RobertPitt

1
(funzione () {}) significa che restituisce la funzione interna? Cosa significa esattamente "()"?
Jaskey,

Mi piace il primo esempio ma il secondo usando i riferimenti al numero di riga (che non è una funzione js) non è chiaro.
Samy Bencherif,

1
Si chiama Immediately Invoked Function Expression (IIFE): benalman.com/news/2010/11/…
Andres Rojas,

1
Ho molti problemi a comprendere la parentesi esterna di ( function(){} ): che cos'è esattamente? Non posso semplicemente scrivere function(){}()?
TMOTTM

127

Al livello più elementare, qualcosa del modulo (function(){...})()è una funzione letterale che viene eseguita immediatamente. Ciò significa che hai definito una funzione e la stai chiamando immediatamente.

Questo modulo è utile per nascondere e incapsulare informazioni poiché qualsiasi cosa tu definisca all'interno di quella funzione rimane locale a quella funzione e inaccessibile dal mondo esterno (a meno che tu non la esponga specificamente, di solito tramite un oggetto restituito letterale).

Una variante di questo modulo di base è ciò che vedi nei plugin jQuery (o in questo modello di modulo in generale). Quindi:

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

Ciò significa che stai passando un riferimento jQueryall'oggetto reale , ma è noto come $nell'ambito della funzione letterale.

Il tipo 1 non è in realtà un plug-in. Stai semplicemente assegnando un oggetto letterale a jQuery.fn. In genere si assegna una funzione jQuery.fnpoiché i plugin sono generalmente solo funzioni.

Il tipo 2 è simile al tipo 1; non stai davvero creando un plugin qui. Stai semplicemente aggiungendo un oggetto letterale a jQuery.fn.

Tipo 3 è un plugin, ma non è il modo migliore o più semplice per crearne uno.

Per saperne di più su questo, dai un'occhiata a questa domanda e risposta simile . Inoltre, questa pagina fornisce alcuni dettagli sull'autore dei plugin.


1
Non sono sicuro di come il Tipo 3 stia estendendo il core. È un modo perfettamente valido per creare un plug-in poiché stai estendendo il prototipo. Anche se un po 'inutile.
tbranyen,

1
Mio male - avrei dovuto essere più chiaro. Avevo fretta e hai ragione.
Vivin Paliath

32

Un piccolo aiuto:

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


21

Solo una piccola aggiunta alla spiegazione

Questa struttura (function() {})();si chiama IIFE (Espressione di funzione immediatamente richiamata), verrà eseguita immediatamente quando l'interprete raggiungerà questa linea. Quindi quando scrivi queste righe:

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

ciò significa che l'interprete invocherà immediatamente la funzione e passerà jQuerycome parametro, che verrà utilizzato all'interno della funzione come $.


12

In realtà, questo esempio mi ha aiutato a capire cosa (function($) {})(jQuery);significa.

Considera questo:

// 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

E ora considera questo:

  • jQuery è una variabile che contiene l'oggetto jQuery.
  • $è un nome di variabile come un altro ( a, $b, a$betc.) e che non ha alcun significato speciale come in PHP.

Sapendo che possiamo dare un'altra occhiata al nostro esempio:

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

Per me questa è la risposta migliore. chiaro e così semplice
Saleh,

11

Digitare 3, per funzionare dovrebbe apparire così:

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

Non sono sicuro del motivo per cui qualcuno dovrebbe estendersi semplicemente impostando direttamente la proprietà nel prototipo jQuery, sta facendo la stessa cosa esatta solo in più operazioni e più disordine.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.