Зачем определять анонимную функцию и передавать ее jQuery в качестве аргумента?

Я просматриваю отличный демонстрационный код peepcode с скринкастов backbone.js. В нем весь код оболочки заключен в анонимную функцию, передаваемую объектом jQuery:

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

В моем собственном кодовом коде, я только что завернул весь мой код в событии jQuery DOM "ready":

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

Какая точка/преимущество первого подхода? Выполнение этого способа создает анонимную функцию, которая затем выполняется немедленно с передачей объекта jQuery в качестве аргумента функции, эффективно гарантируя, что $является объектом jQuery. Это единственный момент - гарантировать, что jQuery привязан к "$" или есть другие причины для этого?

Ответ 1

Два блока кода, которые вы показали, сильно отличаются в том, когда и почему они выполняются. Они не исключают друг друга. Они не выполняют одну и ту же цель.

Модули JavaScript


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

Это шаблон "JavaScript Module", реализованный с помощью функции мгновенного вызова.

Цель этого кода - предоставить "модульность", конфиденциальность и инкапсуляцию для вашего кода.

Реализация этой функции - это функция, которая немедленно вызывается вызывающей скобкой (jQuery). Цель передачи jQuery в круглые скобки состоит в том, чтобы предоставить локальную область определения глобальной переменной. Это помогает уменьшить количество накладных расходов при поиске переменной $ и позволяет в лучшем случае улучшить сжатие/оптимизацию для minifiers.

Немедленно вызывающие функции выполняются, ну, немедленно. Как только определение функции будет завершено, функция будет выполнена.

Функция jQuery "DOMReady"

Это псевдоним функции jQuery "DOMReady" : http://api.jquery.com/ready/


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

Функция jQuery "DOMReady" выполняется, когда DOM готов к работе с вашим кодом JavaScript.

Модули против DOMReady В базовом коде

Плохая форма для определения вашего кода базовой линии внутри функции jQuery DOMReady и потенциально может повредить производительность вашего приложения. Эта функция не вызывается до тех пор, пока DOM не загрузится и не будет обработана. Это означает, что вы ожидаете, пока браузер не разберет DOM хотя бы один раз, прежде чем вы определяете свои объекты.

Лучше всего определить объекты Backbone вне функции DOMReady. Я, среди многих других, предпочитаю делать это внутри шаблона модуля JavaScript, чтобы я мог обеспечить инкапсуляцию и конфиденциальность моего кода. Я предпочитаю использовать шаблон "Revealing Module" (см. Первую ссылку выше), чтобы обеспечить доступ к битам, которые мне нужны вне моего модуля.

Определяя свои объекты за пределами функции DOMReady и предоставляя некоторый способ их ссылки, вы позволяете браузеру начать работу над обработкой вашего JavaScript, что потенциально ускорит работу пользователя. Это также делает код более гибким, так как вы можете перемещать вещи, не беспокоясь о создании дополнительных функций DOMREIDE, когда вы перемещаете вещи.

Вероятнее всего, вы будете использовать функцию DOMReady, даже если вы определяете объекты Backbone в другом месте. Причина в том, что многим Backbone-приложениям необходимо каким-то образом манипулировать DOM. Для этого вам нужно подождать, пока DOM будет готов, поэтому вам нужно использовать функцию DOMReady для запуска вашего приложения после того, как оно определено.

Вы можете найти множество примеров этого в Интернете, но здесь очень простая реализация, использующая как модуль, так и функцию 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();
});

Ответ 2

В качестве второстепенного sidenote отправка в $в качестве аргумента анонимной функции делает $local этой функции, которая имеет небольшую положительную производительность, если функция $называется много. Это связано с тем, что javascript сначала ищет локальную область для переменных, а затем пересекает весь путь до области окна (где обычно живет).

Ответ 3

Это гарантирует, что вы можете всегда использовать $ внутри этого закрытия, даже если $.noConflict().

Без этого закрытия вы должны использовать jQuery вместо $ все время.

Ответ 4

Следует избегать потенциального конфликта переменной $. Если что-то еще определяет переменную с именем $, ваш плагин может использовать неправильное определение

Подробнее см. http://docs.jquery.com/Plugins/Authoring#Getting_Started

Ответ 5

Используйте оба параметра.

Функция самозапуска, в которой вы передаете jQuery для предотвращения конфликтов библиотек, и просто убедитесь, что jQuery доступен, как вы ожидали бы с помощью $.

И метод ярлыка .ready(), необходимый для запуска javascript только после загрузки DOM:

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

    //and rest of code here
})(jQuery);