Анонимная функция против отдельной именованной функции для инициализации в jquery

9

Допустим, у нас есть некоторый код, который используется для инициализации вещей при загрузке страницы, и это выглядит так:

function initStuff() { ...}
...
$(document).ready(initStuff);

Функция initStuff вызывается только из третьей строки фрагмента. Больше никогда. Поэтому обычно люди помещают это в анонимный обратный вызов, например:

$(document).ready(function() { 
    //Body of initStuff
});

Наличие функции в выделенном месте в коде на самом деле не помогает с удобочитаемостью, потому что при вызове метода ready () становится очевидным, что это код инициализации.

Есть ли другие причины отдавать предпочтение одному?

Мартин Н.
источник
4
Первый из них загромождает глобальное пространство имен. Выбери второе.
riwalk

Ответы:

10

Как упомянул @ Stargazer712, первое загромождает глобальное пространство имен, поэтому второе - победитель ИМХО. Теперь, сказав, что, поскольку вы используете анонимную функцию во втором примере, стек вызовов вашего отладчика будет бесполезным и получит различные результаты в зависимости от используемого отладчика. Как правило, в итоге я получаю:

$(document).ready(function MODULE_init() { 
    //Body of initStuff
});

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

Я склонен использовать вышеупомянутое соглашение во всех определениях анонимных (ну, больше не анонимных;)) функций. Это соглашение, которое я нашел при просмотре кода JS в Firefox.

Изменить: Теперь, сказав все это, Оливер поднимает хороший вопрос с модульных тестов. Вышеуказанное предназначено для использования в качестве оболочки для более сложных операций, а не для хранения тонны непроверенного кода.

Демиан Брехт
источник
+1 За упоминание отладки. Я часто видел использование «именованных обратных вызовов» (не знаю, существует ли этот термин на самом деле) в коде Node.js, поэтому я тоже думаю, что это хорошая практика.
Оливер Вейлер
kangax.github.com/nfe Выражения именованных функций - эта статья расскажет вам все, что вы когда-либо хотели знать о них.
Шон Макмиллан
7

Я бы сказал, что в этом случае это, вероятно, не имеет значения, но если у вас есть анонимные функции обратного вызова, вызывающие другие анонимные функции обратного вызова, я склонен использовать первый подход, поскольку он делает код намного более читабельным и более легким для понимания.

Что касается модульного тестирования, первый подход будет лучше, поскольку вы сможете протестировать initstuffфункцию изолированно.

Оливер Вейлер
источник
Обычно у нас не так много кода в этих функциях инициализации. Он может получить некоторые данные из нескольких мест, вот и все
Мартин Н.
3

Я бы выбрал первый - для удобочитаемости / отладки / тестирования и т. Д. Вы можете избежать проблемы с беспорядком в глобальном пространстве имен, просто создав локальное пространство имен для всех функций на вашей странице. Я использую стиль обозначения объекта в соответствии с рекомендациями Пола Айриша (см. Слайды 13-15 на http://paulirish.com/2009/perf/ )

var MYPAGE = {
  onReady : function(){
  // init code
  },
  someOtherCallback : function(){}
};

jQuery(document).ready(MYPAGE.onReady);
njaggars
источник
2

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

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

Это короткий и избегает поиска документа DOM, как

jQuery(document).ready(function(){...}); 

делает.

Alex
источник
+1: я думаю, что это стандартная практика, но во избежание проблем с противоречивыми определениями $я предпочитаю:jQuery(function($) {...});
Кевин Клайн