JavaScript: подставляемые функции по сравнению с предопределенными функциями

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

Т.е. который лучше:

(function() {
  setTimeout(function() { /*some code here*/ }, 5);
})();

по сравнению с

(function() {
  function invokeMe() {
    /*code*/
  }
  setTimeout(invokeMe, 5);
})();


Странный вопрос, но мы почти боремся в команде об этом.

44
задан informatik01 27 March 2019 в 13:58
поделиться

8 ответов

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

2
ответ дан 26 November 2019 в 22:08
поделиться

Нет технических причин отдавать предпочтение одной версии над другим. Для меня это обычно зависит от двух вещей:

  1. Я хочу повторно использовать переданный обратный вызов в другом контексте. В этом случае я определяю функцию как автономную и передаю ссылку.
  2. Обратный вызов превышает ~ 10 строк кода, и функция ожидает дополнительных аргументов после обратного вызова. В этом случае трудно восстановить, какие значения фактически передаются в функцию.

Пример:

setTimeout(function() { // I need to scroll to see the other arguments

  // many lines of code

}, 0); // <- where does this '0' belong to?
0
ответ дан 26 November 2019 в 22:08
поделиться

Я предпочитаю использовать именованные функции. Именованные функции отображаются по имени во всех отладчиках (air, firebug, IE).

Пример:

Обратите внимание, что вы также можете иметь встроенные именованные функции, такие как

{
    method: function obj_method(){}
}

Таким образом, когда вы посмотрите на трассировку стека, вы увидите функцию obj_method вместо анонимной.

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

0
ответ дан 26 November 2019 в 22:08
поделиться

В приведенном примере объявление и использование функции настолько близки, что я думаю, единственная разница - удобочитаемость. Я предпочитаю второй пример.

0
ответ дан 26 November 2019 в 22:08
поделиться

Между ними есть одно существенное различие: у последнего есть имя.

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

(function(){
  function invokeMe() {
    /*code*/
  }
  setTimeout(invokeMe, 5);
})();

... в целом. Однако правила предназначены для нарушения, а не для рабского подчинения. : -)

Обратите внимание, что согласно спецификации есть третья альтернатива: у вас может быть встроенная функция, которая также имеет имя:

(function(){
  setTimeout(function invokeMe(){ /*some code here*/ }, 5);
})();

Проблема, однако, в том, что все версии интерпретатора JavaScript от Microsoft («JScript»), в том числе (что удивительно) в IE9, неправильно обрабатывает то выражение функции с именем и создает две совершенно разные функции в разное время. ( Доказательство , попробуйте его в IE9 или более ранней версии, а также практически в любом другом браузере.) IE ошибается двумя способами: 1. Он создает два отдельных функциональных объекта и 2. Как следствие одного. из них он "выводит" символ имени за пределы области видимости выражения (в явном нарушении раздела 13 спецификации). Подробности здесь: Двойной дубль

11
ответ дан 26 November 2019 в 22:08
поделиться

IMO, объявление функции будет полезно только в том случае, если вы намереваетесь повторно использовать ее позже каким-либо другим способом.

Я лично использую функциональные выражения (первый способ) для обработчиков setTimeout .

Однако вы, возможно, захотите узнать различий между объявлениями функций и выражениями функций, я рекомендую вам следующую статью:

5
ответ дан 26 November 2019 в 22:08
поделиться

Я думаю, что единственная разница в подобном коде состоит в том, что с помощью второго фрагмента кода вы можете повторно вызвать ту же функцию (иногда это полезно с «функциями таймера»):

(function(){
  function invokeMe() {
    if(..) setTimeout(invokeMe, 5);
  }
  setTimeout(invokeMe, 5);
})();
1
ответ дан 26 November 2019 в 22:08
поделиться

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

Если серьезно, в конце концов, это не имеет значения. Первая форма (безымянные функции) имеет тенденцию становиться громоздкой с большими функциями, но не имеет большого значения для небольших (1-2 строчных) функций. Вторая форма также безвредна.

Любой аргумент против любого стиля является чистым байкшеддингом , имо.

3
ответ дан 26 November 2019 в 22:08
поделиться
Другие вопросы по тегам:

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