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

86

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

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

В своем собственном магистральном коде я только что завернул весь свой код в JQuery DOM 'ready' apos; событие:

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

В чем смысл / преимущество первого подхода? Делая это таким образом, вы создаете анонимную функцию, которая затем сразу же выполняется с объектом jQuery, передаваемым в качестве аргумента функции, эффективно гарантируя, что $ является объектом jQuery. Является ли это единственным пунктом - чтобы гарантировать, что jQuery привязан к & quot; $ & ap; или есть другие причины для этого?

Возможный дубликат:jQuery and $ questions Alexander
Смотрите возможные дубликатыjQuery document.ready vs self calling anonymous function за разницу Bergi
Взаимодействие с другими библиотеками - если автор страницы должен использовать$.noConflict()Первый пример все еще будет работать. DCoder
@ Александр, но тогда другие люди сначала найдут этот вопрос на SO. :-) caiosm1005
Вы должны сначала просмотреть SO. Alexander

Ваш Ответ

5   ответов
13

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

166

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

JavaScript Modules

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

Это & quot; Модуль JavaScript & quot; шаблон, реализованный с помощью немедленно вызывающей функции.

http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

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

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

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

jQuery's "DOMReady" function

Это псевдоним для JQuery's DOMReady. функция:http://api.jquery.com/ready/


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

JQuery & s; DOMReady & quot; Функция выполняется, когда DOM готов манипулировать вашим кодом JavaScript.

Modules vs DOMReady In Backbone Code

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

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

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

Вы, вероятно, по-прежнему будете использовать функцию 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();
});
Не забывайте, что шаблон модуля javascript также называетсяIIFE.
Спасибо за этот подробный ответ. Я знал о функции DOMReady, вызываемой только при возникновении события готовности DOM, но никогда не думал, что это станет проблемой. Разделение кода на определение базовых битов внутри модуля, а затем взаимодействие с ними в dom ready действительно кажется лучшим подходом Matt Roberts
анонимные функции выполняются в то же время, что и DOM ready, так как же сделать их более эффективными?
Интересно, что «todo» Пример приложения с магистральным src помещает все в готовый дом. Matt Roberts
4

Если что-то определяет переменную с именем $, ваш плагин может использовать неправильное определение

Ссылаться наhttp://docs.jquery.com/Plugins/Authoring#Getting_Started Больше подробностей

0

Самопризывающая функция, в которой вы передаете 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);
Более короткая версия, которую я нашел в другом месте на SO(also protects undefined): jQuery(function ($, undefined) { /* Code */ });
9

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

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

Похожие вопросы