(function() {})()
i jego kuzyn specyficzny dla jQuery (function($) {})(jQuery)
pojawiają się cały czas w kodzie Javascript.
Jak działają te konstrukcje i jakie problemy rozwiązują?
Docenione przykłady
javascript
Tom Lehman
źródło
źródło
jQuery
się argument.Odpowiedzi:
Wraz ze wzrostem popularności frameworków JavaScript,
$
znak ten był używany przy wielu różnych okazjach. Tak więc, aby złagodzić możliwe konflikty, możesz użyć tych konstrukcji:(function ($){ // Your code using $ here. })(jQuery);
W szczególności jest to anonimowa deklaracja funkcji, która jest wykonywana natychmiastowo z przekazaniem głównego obiektu jQuery jako parametru. Wewnątrz tej funkcji możesz
$
odwoływać się do tego obiektu, nie martwiąc się, że inne struktury również znajdują się w zakresie.źródło
Jest to technika używana do ograniczania zakresu zmiennej; jest to jedyny sposób, aby zapobiec zanieczyszczaniu globalnej przestrzeni nazw przez zmienne.
var bar = 1; // bar is now part of the global namespace alert(bar); (function () { var foo = 1; // foo has function scope alert(foo); // code to be executed goes here })();
źródło
1) Definiuje anonimową funkcję i wykonuje ją od razu.
2) Zwykle robi się to tak, aby nie zanieczyszczać globalnej przestrzeni nazw niechcianym kodem.
3) Musisz ujawnić niektóre metody z niego, wszystko zadeklarowane wewnątrz będzie „prywatne”, na przykład:
MyLib = (function(){ // other private stuff here return { init: function(){ } }; })();
Lub alternatywnie:
MyLib = {}; (function({ MyLib.foo = function(){ } }));
Chodzi o to, że można go używać na wiele sposobów, ale efekt pozostaje taki sam.
źródło
To tylko anonimowa funkcja, która jest wywoływana natychmiast. Możesz najpierw utworzyć funkcję, a następnie ją wywołać i otrzymasz ten sam efekt:
(function(){ ... })();
pracuje jako:
temp = function(){ ... }; temp();
To samo możesz zrobić z nazwaną funkcją:
function temp() { ... } temp();
Kod, który nazywasz specyficznym dla jQuery, jest taki, że używasz w nim obiektu jQuery. To po prostu anonimowa funkcja z parametrem, która jest wywoływana natychmiast.
Możesz zrobić to samo w dwóch krokach i możesz to zrobić z dowolnymi parametrami:
temp = function(answer){ ... }; temp(42);
Problem, który to rozwiązuje, polega na tym, że tworzy zamknięcie dla kodu w funkcji. Możesz zadeklarować w nim zmienne bez zanieczyszczania globalnej przestrzeni nazw, zmniejszając w ten sposób ryzyko konfliktów podczas używania jednego skryptu razem z drugim.
W konkretnym przypadku dla jQuery używasz go w trybie zgodności, w którym nie deklaruje nazwy $ jako aliasu dla jQuery. Wysyłając obiekt jQuery do domknięcia i nazywając parametr $, nadal można używać tej samej składni, co bez trybu zgodności.
źródło
Wyjaśnia tutaj, że twoja pierwsza konstrukcja zapewnia zakres dla zmiennych.
(function() { var myProperty = "hello world"; alert(myProperty); })(); alert(typeof(myProperty)); // undefined
źródło
Innym powodem, aby to zrobić, jest usunięcie wszelkich niejasności co do tego, którego
$
operatora frameworka używasz. Na przykład, aby wymusić działanie jQuery, możesz wykonać:;(function($){ ... your jQuery code here... })(jQuery);
Przekazując
$
operator jako parametr i wywołując go w jQuery,$
operator w funkcji jest zablokowany na jQuery, nawet jeśli masz załadowane inne platformy.źródło
Innym zastosowaniem tej konstrukcji jest „przechwytywanie” wartości zmiennych lokalnych, które zostaną użyte w zamknięciu. Na przykład:
for (var i = 0; i < 3; i++) { $("#button"+i).click(function() { alert(i); }); }
Powyższy kod spowoduje wyświetlenie wszystkich trzech przycisków jako „3”. Z drugiej strony:
for (var i = 0; i < 3; i++) { (function(i) { $("#button"+i).click(function() { alert(i); }); })(i); }
Spowoduje to wyświetlenie trzech przycisków zgodnie z oczekiwaniami jako „0”, „1” i „2”.
Powodem tego jest to, że zamknięcie zachowuje odniesienie do otaczającej ramki stosu , która przechowuje bieżące wartości swoich zmiennych. Jeśli te zmienne zmienią się przed wykonaniem zamknięcia, wówczas zamknięcie zobaczy tylko najnowsze wartości, a nie wartości takie, jakie były w momencie utworzenia zamknięcia. Dzięki zawinięciu kreacji zamknięcia wewnątrz innej funkcji, jak w drugim przykładzie powyżej, bieżąca wartość zmiennej
i
jest zapisywana w ramce stosu funkcji anonimowej.źródło
Jest to uważane za zamknięcie . Oznacza to, że zawarty kod będzie działał we własnym zakresie leksykalnym. Oznacza to, że możesz zdefiniować nowe zmienne i funkcje, które nie będą kolidować z przestrzenią nazw używaną w kodzie poza zamknięciem.
var i = 0; alert("The magic number is " + i); (function() { var i = 99; alert("The magic number inside the closure is " + i); })(); alert("The magic number is still " + i);
Spowoduje to wygenerowanie trzech wyskakujących okienek, pokazujących, że
i
w zamknięciu nie zmienia istniejącej wcześniej zmiennej o tej samej nazwie:źródło
Są często używane we wtyczkach jQuery. Jak wyjaśniono w Przewodniku po tworzeniu wtyczek jQuery, wszystkie zmienne zadeklarowane wewnątrz
{ }
są prywatne i nie są widoczne na zewnątrz, co pozwala na lepszą hermetyzację.źródło
{}
nie tworzą samodzielnie nowego zakresu w JavaScript. Zakres jest tworzony przez deklarację funkcji.Jak powiedzieli inni, obaj definiują funkcje anonimowe, które są wywoływane natychmiast. Generalnie zawijam deklaracje klas JavaScript w tę strukturę, aby utworzyć statyczny zakres prywatny dla klasy. Mogę wtedy umieścić stałe dane, metody statyczne, programy obsługi zdarzeń lub cokolwiek innego w tym zakresie i będzie to widoczne tylko dla instancji klasy:
// Declare a namespace object. window.MyLibrary = {}; // Wrap class declaration to create a private static scope. (function() { var incrementingID = 0; function somePrivateStaticMethod() { // ... } // Declare the MyObject class under the MyLibrary namespace. MyLibrary.MyObject = function() { this.id = incrementingID++; }; // ...MyObject's prototype declaration goes here, etc... MyLibrary.MyObject.prototype = { memberMethod: function() { // Do some stuff // Maybe call a static private method! somePrivateStaticMethod(); } }; })();
W tym przykładzie
MyObject
klasa jest przypisana doMyLibrary
przestrzeni nazw, więc jest dostępna.incrementingID
isomePrivateStaticMethod()
nie są bezpośrednio dostępne poza zakresem funkcji anonimowej.źródło
To jest po prostu przestrzeń nazw kodu JavaScript.
Na przykład możesz umieścić w nim dowolne zmienne lub funkcje, a z zewnątrz nie istnieją w tym zakresie. Więc kiedy hermetyzujesz tam wszystko, nie musisz się martwić o starcia.
Na
()
końcu oznacza to samo przywołanie. Możesz tam również dodać argument, który stanie się argumentem Twojej funkcji anonimowej. Robię to często z jQuery i widać, dlaczego ...(function($) { // Now I can use $, but it won't affect any other library like Prototype })(jQuery);
Evan Trimboli zajmuje się resztą w swojej odpowiedzi .
źródło
To funkcja samo-wywołująca się. Coś w rodzaju skrótu do pisania
function DoSomeStuff($) { } DoSomeStuff(jQuery);
źródło
Powyższy kod tworzy anonimową funkcję w linii 1, a następnie wywołuje ją w linii 3 z 0 argumentami. To skutecznie hermetyzuje wszystkie funkcje i zmienne zdefiniowane w tej bibliotece, ponieważ wszystkie funkcje będą dostępne tylko w tej anonimowej funkcji.
Jest to dobra praktyka, a jej powodem jest unikanie zanieczyszczania globalnej przestrzeni nazw zmiennymi i funkcjami, które mogłyby zostać zablokowane przez inne elementy JavaScript w całej witrynie.
Aby wyjaśnić, jak wywoływana jest funkcja, rozważ prosty przykład:
Jeśli masz dołączony ten pojedynczy wiersz JavaScript, zostanie on wywołany automatycznie bez jawnego wywoływania go:
alert('hello');
Więc weź ten pomysł i zastosuj go do tego przykładu:
(function() { alert('hello') //anything I define in here is scoped to this function only }) (); //here, the anonymous function is invoked
Wynik końcowy jest podobny, ponieważ funkcja anonimowa jest wywoływana tak jak w poprzednim przykładzie.
źródło
//here, the anonymous function is invoked
, proste, ale wcześniej tego nie widziałem :)Ponieważ
dobreodpowiedzi na kod są już zajęte :) Dorzucę sugestię, aby obejrzeć kilka filmów wideo Johna Resiga wideo 1 , wideo 2 (wynalazca jQuery i master w JavaScript).Kilka naprawdę dobrych spostrzeżeń i odpowiedzi zawartych w filmach.
Właśnie to robiłem w chwili, gdy zobaczyłem twoje pytanie.
źródło
function(){ // some code here }
to sposób na zdefiniowanie anonimowej funkcji w javascript. Mogą dać ci możliwość wykonania funkcji w kontekście innej funkcji (gdzie w przeciwnym razie możesz nie mieć takiej możliwości).
źródło