Может любое тело бросать меня некоторые аргументы в пользу использования подставляемых функций против передачи предопределенного имени функции к некоторому обработчику.
Т.е. который лучше:
(function() {
setTimeout(function() { /*some code here*/ }, 5);
})();
по сравнению с
(function() {
function invokeMe() {
/*code*/
}
setTimeout(invokeMe, 5);
})();
Странный вопрос, но мы почти боремся в команде об этом.
Встроенная функция позволяет избежать загрязнения пространства имен, а предопределенные функции имеют более частое повторное использование. Я думаю, вы могли бы привести случаи, когда каждый из них подходит.
Нет технических причин отдавать предпочтение одной версии над другим. Для меня это обычно зависит от двух вещей:
Пример:
setTimeout(function() { // I need to scroll to see the other arguments
// many lines of code
}, 0); // <- where does this '0' belong to?
Я предпочитаю использовать именованные функции. Именованные функции отображаются по имени во всех отладчиках (air, firebug, IE).
Пример:
Обратите внимание, что вы также можете иметь встроенные именованные функции, такие как
{
method: function obj_method(){}
}
Таким образом, когда вы посмотрите на трассировку стека, вы увидите функцию obj_method вместо анонимной.
Вы спрашивали, когда нужно встроить функцию, а не объявлять ее? Когда это имеет смысл в коде. Если он вам нужен из двух разных мест, он не может быть встроенным. Иногда встроенный код упрощает чтение, иногда - сложнее.
В приведенном примере объявление и использование функции настолько близки, что я думаю, единственная разница - удобочитаемость. Я предпочитаю второй пример.
Между ними есть одно существенное различие: у последнего есть имя.
Мне нравится, когда мои инструменты помогают мне, и поэтому я в основном избегаю анонимных функций , поскольку мои инструменты не могут предоставить мне значимую информацию о них (например, в списке стека вызовов в отладчике, так далее.). Так что я бы выбрал форму
(function(){
function invokeMe() {
/*code*/
}
setTimeout(invokeMe, 5);
})();
... в целом. Однако правила предназначены для нарушения, а не для рабского подчинения. : -)
Обратите внимание, что согласно спецификации есть третья альтернатива: у вас может быть встроенная функция, которая также имеет имя:
(function(){
setTimeout(function invokeMe(){ /*some code here*/ }, 5);
})();
Проблема, однако, в том, что все версии интерпретатора JavaScript от Microsoft («JScript»), в том числе (что удивительно) в IE9, неправильно обрабатывает то выражение функции с именем и создает две совершенно разные функции в разное время. ( Доказательство , попробуйте его в IE9 или более ранней версии, а также практически в любом другом браузере.) IE ошибается двумя способами: 1. Он создает два отдельных функциональных объекта и 2. Как следствие одного. из них он "выводит" символ имени за пределы области видимости выражения (в явном нарушении раздела 13 спецификации). Подробности здесь: Двойной дубль
IMO, объявление функции будет полезно только в том случае, если вы намереваетесь повторно использовать ее позже каким-либо другим способом.
Я лично использую функциональные выражения (первый способ) для обработчиков setTimeout
.
Однако вы, возможно, захотите узнать различий между объявлениями функций и выражениями функций, я рекомендую вам следующую статью:
Я думаю, что единственная разница в подобном коде состоит в том, что с помощью второго фрагмента кода вы можете повторно вызвать ту же функцию (иногда это полезно с «функциями таймера»):
(function(){
function invokeMe() {
if(..) setTimeout(invokeMe, 5);
}
setTimeout(invokeMe, 5);
})();
Я предлагаю полную дуэль между членами противостоящей команды, чтобы разрешить такие споры.
Если серьезно, в конце концов, это не имеет значения. Первая форма (безымянные функции) имеет тенденцию становиться громоздкой с большими функциями, но не имеет большого значения для небольших (1-2 строчных) функций. Вторая форма также безвредна.
Любой аргумент против любого стиля является чистым байкшеддингом , имо.