Po co definiować funkcję anonimową i przekazywać ją jako argument jQuery?

Przeglądam doskonały kod demonstracyjny peepcode z szkieletu.js screencasty. W nim kod szkieletowy jest zamknięty w funkcji anonimowej, która jest przekazywana obiektowi jQuery:

(function($) {
  // Backbone code in here
})(jQuery);

W moim kodzie szkieletowym, właśnie zawinąłem cały mój kod w zdarzeniu jQuery DOM 'ready':

$(function(){
  // Backbone code in here
});

Jaki jest cel / zaleta pierwszego podejścia? Robiąc to w ten sposób tworzy anonimową funkcję, która jest następnie natychmiast wykonywana z obiektem jQuery przekazywanym jako argument funkcji, skutecznie zapewniający, że $ jest obiektem jQuery. Czy jest to jedyny punkt-aby zagwarantować, że jQuery jest związane z '$' lub są inne powody, aby to zrobić?

Author: ivarni, 2012-04-29

5 answers

Dwa bloki kodu, które pokazałeś, różnią się znacznie pod względem czasu i powodu ich wykonania. Nie wykluczają się nawzajem. Nie służą one temu samemu celowi.

Moduły JavaScript


(function($) {
  // Backbone code in here
})(jQuery);

Jest to wzorzec "modułu JavaScript", zaimplementowany z natychmiastowym wywołaniem funkcja.

Celem tego kodu jest zapewnienie" modułowości", Prywatności i hermetyzacji kodu.

Implementacja tej funkcji jest natychmiast wywoływana przez wywołanie nawiasu (jQuery). Celu przekazania jQuery do nawias ma zapewnić lokalny zasięg zmiennej globalnej. Pomaga to zmniejszyć ilość kosztów wyszukiwania zmiennej $ i pozwala na lepszą kompresję / optymalizację minifigurek w niektórych przypadkach.

Natychmiast wywołujące funkcje są wykonywane, cóż, natychmiast. Gdy tylko definicja funkcji jest kompletna, funkcja jest wykonywana.

Funkcja "DOMReady" JQuery

Jest to alias do funkcji "DOMReady" jQuery: http://api.jquery.com/ready/


$(function(){
  // Backbone code in here
});

JQuery 's" DOMReady " funkcja wykonuje, gdy DOM jest gotowy do manipulowania przez kod JavaScript.

Moduły vs DOMReady w kodzie szkieletowym

To zła forma definiowania kodu szkieletowego wewnątrz funkcji DOMReady jQuery i potencjalnie szkodliwa dla wydajności aplikacji. Funkcja ta nie zostanie wywołana, dopóki DOM nie zostanie załadowany i nie będzie gotowy do manipulowania. Oznacza to, że czekasz aż przeglądarka parsował DOM przynajmniej raz przed definiowaniem obiektów.

Lepszym pomysłem jest zdefiniowanie obiektów szkieletowych poza funkcją DOMReady. Ja, między innymi, wolę to zrobić wewnątrz wzorca modułu JavaScript, aby zapewnić enkapsulację i prywatność dla mojego kodu. Zazwyczaj używam wzorca "Revealing Module" (zobacz pierwszy link powyżej), aby zapewnić dostęp do bitów, których potrzebuję poza moim modułem.

Definiując obiekty poza domready funkcja, i zapewniając jakiś sposób, aby je odwołać, pozwalasz przeglądarce, aby uzyskać przewagę nad przetwarzaniem JavaScript, potencjalnie przyspieszając doświadczenie użytkownika. Sprawia to również, że kod jest bardziej elastyczny, ponieważ możesz przenosić rzeczy bez martwienia się o tworzenie większej liczby funkcji DOMREady podczas przenoszenia rzeczy.

Prawdopodobnie będziesz używać funkcji DOMReady, mimo to, nawet jeśli zdefiniujesz swoje obiekty szkieletowe gdzie indziej. Powodem jest to, że wiele aplikacji szkieletowych potrzebuje manipulować DOM w jakiś sposób. Aby to zrobić, musisz poczekać, aż DOM będzie gotowy, dlatego musisz użyć funkcji DOMReady, aby uruchomić aplikację po jej zdefiniowaniu.

Możesz znaleźć wiele przykładów tego w Internecie, ale oto bardzo podstawowa implementacja, wykorzystująca zarówno Moduł, jak i funkcję DOMReady:



// Define "MyApp" as a revealing module

MyApp = (function(Backbone, $){

  var View = Backbone.View.extend({
    // do stuff here  
  });

  return {
    init: function(){
      var view = new View();
      $("#some-div").html(view.render().el);
    }
  };

})(Backbone, jQuery);



// Run "MyApp" in DOMReady

$(function(){
  MyApp.init();
});
 162
Author: Derick Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-29 13:20:20

Jako podrzędna Uwaga boczna, wysłanie $ jako argumentu do funkcji anonimowej powoduje, że $ local dla tej funkcji ma małą pozytywną implikację wydajności, jeśli funkcja $ jest wywoływana dużo. Dzieje się tak dlatego, że javascript najpierw przeszukuje lokalny zakres zmiennych, a następnie przechodzi w dół aż do zakresu okna (gdzie zwykle żyje$).

 13
Author: joidegn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-23 14:34:46

Zapewnia, że możesz Zawsze używać $ wewnątrz tego zamknięcia, nawet jeśli $.noConflict() został użyty.

Bez tego zamknięcia powinieneś używać jQuery zamiast $ przez cały czas.

 9
Author: ThiefMaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-29 10:56:43

Ma to na celu uniknięcie potencjalnego konfliktu zmiennej$. Jeśli coś innego definiuje zmienną o nazwie$, wtyczka może użyć niewłaściwej definicji

Zobacz http://docs.jquery.com/Plugins/Authoring#Getting_Started Po Więcej Szczegółów

 4
Author: Andrew Brock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-29 10:55:31

Użyj obu.

Funkcja self wywołująca, w której przekazujesz jQuery, aby zapobiec konfliktom bibliotek i upewnić się, że jQuery jest dostępny tak, jak można się spodziewać po $.

I ... metoda skrótu ready() wymagana do uruchomienia javascript dopiero po załadowaniu DOM:

(function($) {
    $(function(){
          //add code here that needs to wait for page to be loaded
    });

    //and rest of code here
})(jQuery);
 0
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-12 14:38:26