Co robi (funkcja ($) {}) (jQuery); oznaczać?

299

Zaczynam od pisania wtyczek jQuery. Napisałem trzy małe wtyczki, ale po prostu kopiowałem linię do wszystkich moich wtyczek, nie wiedząc, co to znaczy. Czy ktoś może mi powiedzieć coś więcej na ten temat? Być może kiedyś przyda się wyjaśnienie przy pisaniu frameworka :)

Co to robi? (Wiem, że jakoś rozszerza jQuery, ale czy jest coś jeszcze ciekawego do powiedzenia na ten temat)

(function($) {

})(jQuery);

Jaka jest różnica między następującymi dwoma sposobami pisania wtyczki:

Typ 1:

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

        },

        $.fn.jPluginName.defaults = {

        }
})(jQuery);

Typ 2:

(function($) {
    $.jPluginName = {

        }
})(jQuery);

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

Mógłbym być tutaj daleko i być może wszystkie oznaczają to samo. Jestem zdezorientowany. W niektórych przypadkach, to nie wydaje się działać w wtyczce że pisałem używając Type 1. Do tej pory, typ 3 wydaje się najbardziej elegancki do mnie, ale chciałbym wiedzieć o innych.

Legenda
źródło
22
To łóżko czasu tutaj, ale tylko na początek, (function($) { })(jQuery);okłady kod tak, że $jest jQuerywewnątrz tego zamknięcia, nawet jeśli $oznacza coś innego poza nim, zazwyczaj w wyniku $.noConflict()na przykład. To gwarantuje, że Twoja wtyczka działa, niezależnie od tego, czy nie $ === jQuery :)
Nick Craver
3
O (function($) { })(jQuery)tobie powiedziałeś: „Wiem, że rozszerza jQuery [...]”. Oczywiście nie wiesz, ponieważ twoje oświadczenie jest w 100% fałszywe. Nawiasem mówiąc, może być mylące dla przyszłych czytelników. Spójrz na to: stackoverflow.com/a/32550649/1636522 .
liść
W komentarzach @ NickCraver, jquery-ui-1.7.2.custom.min.js używa tego na przykład: jQuery.ui || (function (c) {var i = c.fn.remove, d = c.browser. mozilla ........}) (jQuery) ;. Wiem, że to stara wersja interfejsu użytkownika jQuery z przestarzałym kodem, ale chodzi o to, aby pokazać, jak w takim przypadku używają „c” zamiast „$”.
Jaime Montoya

Odpowiedzi:

234

Po pierwsze, blok kodu, który wygląda, (function(){})()jest jedynie funkcją wykonywaną w miejscu. Rozwalmy to trochę.

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

Wiersz 2 jest prostą funkcją, owiniętą w nawiasach, aby poinformować środowisko wykonawcze, aby zwróciło funkcję do zakresu nadrzędnego. Po jej zwróceniu funkcja jest wykonywana za pomocą wiersza 4, być może czytanie tych kroków pomoże

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

Widać, że 1 to deklaracja, 2 zwraca funkcję, a 3 po prostu wykonuje funkcję.

Przykład, w jaki sposób zostanie wykorzystany.

(function(doc){

   doc.location = '/';

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

Jeśli chodzi o inne pytania dotyczące wtyczek:

Typ 1: To nie jest właściwie wtyczka, to obiekt przekazywany jako funkcja, ponieważ wtyczki są zwykle funkcjami.

Typ 2: To znowu nie jest wtyczka, ponieważ nie rozszerza $.fn obiektu. To tylko rozszerzenie rdzenia jQuery, chociaż wynik jest taki sam. Dzieje się tak, jeśli chcesz dodać funkcje ruchu, takie jak toArray i tak dalej.

Typ 3: Jest to najlepsza metoda dodania wtyczki, rozszerzony prototyp jQuery pobiera obiekt przechowujący nazwę i funkcję wtyczki i dodaje ją do biblioteki wtyczek.

RobertPitt
źródło
2
jeśli czytasz oryginalne pytanie, PO określa 3 metody pisania zamknięć, nazwał te metody typem {1,2,3}, jestem mętny, odnosząc się do obszarów w pytaniu z odpowiedzią.
RobertPitt
1
(funkcja () {}) oznacza, że ​​zwraca funkcję wewnętrzną? Co dokładnie oznacza „()”?
Jaskey
Podoba mi się pierwszy przykład, ale drugi przy użyciu odniesień do numeru linii (co nie jest cechą js) jest niejasny.
Samy Bencherif
1
To się nazywa Wyrażenie natychmiastowej funkcji (IIFE): benalman.com/news/2010/11/…
Andres Rojas
1
Mam najwięcej problemów ze zrozumieniem zewnętrznego nawiasu ( function(){} ): Co to dokładnie jest? Czy mogę nie tylko pisać function(){}()?
TMOTTM
127

Na najbardziej podstawowym poziomie, coś z formy (function(){...})()jest dosłowną funkcją, która jest wykonywana natychmiast. Oznacza to, że zdefiniowałeś funkcję i wywołujesz ją natychmiast.

Ta forma jest przydatna do ukrywania informacji i enkapsulacji, ponieważ wszystko, co zdefiniujesz wewnątrz tej funkcji, pozostaje lokalne dla tej funkcji i niedostępne ze świata zewnętrznego (chyba że specjalnie ją ujawnisz - zwykle za pomocą literału zwracanego obiektu).

Odmianą tej podstawowej formy jest to, co widać we wtyczkach jQuery (lub ogólnie w tym module). W związku z tym:

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

Co oznacza, że ​​przekazujesz odwołanie do rzeczywistego jQueryobiektu, ale jest ono znane jako $obejmujące literał funkcji.

Typ 1 nie jest tak naprawdę wtyczką. Po prostu przypisujesz obiektowi dosłowność jQuery.fn. Zazwyczaj przypisujesz funkcję do, jQuery.fnponieważ wtyczki są zwykle tylko funkcjami.

Typ 2 jest podobny do Typu 1; tak naprawdę nie tworzysz tutaj wtyczki. Po prostu dodajesz dosłowność obiektu jQuery.fn.

Typ 3 to wtyczka, ale nie jest to najlepszy ani najłatwiejszy sposób na jej utworzenie.

Aby dowiedzieć się więcej na ten temat, spójrz na podobne pytanie i odpowiedz . Również ta strona idzie do jakiegoś szczegółu o authoringu wtyczek.

Vivin Paliath
źródło
1
Nie jestem pewien, jak Typ 3 rozszerza rdzeń. Jest to całkowicie poprawny sposób na utworzenie wtyczki, ponieważ rozbudowujesz prototyp. Chociaż trochę niepotrzebne.
tbranyen
1
Mój zły - powinienem był być bardziej jasny. Spieszyłem się i masz rację.
Vivin Paliath
32

Mała pomoc:

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

liść
źródło
21

Tylko mały dodatek do wyjaśnienia

Struktura ta (function() {})();nosi nazwę IIFE (Natychmiastowe wywołanie funkcji), zostanie wykonana natychmiast, gdy interpreter dojdzie do tej linii. Więc kiedy piszesz te wiersze:

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

oznacza to, że interpreter wywoła funkcję natychmiast i przejdzie jQueryjako parametr, który zostanie użyty w funkcji jako $.

Komercyjne samobójstwo
źródło
12

W rzeczywistości ten przykład pomógł mi zrozumieć, co to (function($) {})(jQuery);znaczy.

Rozważ to:

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

A teraz rozważ to:

  • jQuery jest zmienną przechowującą obiekt jQuery.
  • $Jest to nazwa zmiennej, jak każdy inny ( a, $b, a$bitd.) i nie ma żadnego specjalnego znaczenia jak w PHP.

Wiedząc, że możemy spojrzeć jeszcze raz na nasz przykład:

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
źródło
Dla mnie to najlepsza odpowiedź. jasne i takie proste
Saleh
11

Wpisz 3, aby działać musiałby wyglądać tak:

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

Nie jestem pewien, dlaczego ktoś użyłby przedłużenia po prostu bezpośrednio ustawiając właściwość w prototypie jQuery, robi to samo dokładnie tylko przy większej liczbie operacji i więcej bałaganu.

tbranyen
źródło