Каков предпочтительный способ использования выражения функции Javascript? [закрытый]


Я видел эти различные шаблоны при вызове выражения функции JavaScript:

Шаблон №1

var global = function () {
    return this;
}();

Шаблон №2

var global = (function () {
   return this;
}());

Шаблон #3

var global = (function () {
    return this;
})();

В моих тестированиях все, кажется, работает (по крайней мере, с большинством современных браузеров). На мой "вкус", шаблон #3 лучше, так как он более явный, чем #1, и он возвращает функцию до ее фактического вызова, в отличие от #2.

Но я блуждал, если есть предпочтительный или более правильный вариант...
3 2

3 ответа:

Итак, начальная проблема состоит в том, что код ниже:

function () {

}();

Вызывает исключение. Это потому, что синтаксический анализатор JS не может автоматически определить, является ли это объявлением функции или выражением функции. Все паттерны, которые вы описали, используются, чтобы явно сказать JS: "Эй, чувак, это выражение". Но в вашем конкретном случае у вас нет этой проблемы, потому что если у вас есть переменная впереди, JS прекрасно может понять, что это выражение, а не объявление,и это не вызывает никаких синтаксических ошибок.

В этом конкретном случае нет необходимости в каком-либо "взломе", вы можете просто иметь:

var _global = function () {

}();

И это все. Теперь вопрос: какой " Хак " использовать, когда вам нужно иметь немедленный вызов функции без какой-либо переменной? Все паттерны, которые вы описали, в порядке, Крокфорд, как правило, предпочитает этот:

(function(){

}());

Это имеет смысл для меня, по крайней мере, потому что у вас есть полный изолированный блок, по сравнению с:

(function(){

})();

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

a = b + c
(function() {

}());

В этом сценарии JS рассмотрим c вызов функции:

a = b + c(function() { }());

Чтобы избежать этого, разработчики обычно добавляют точку с запятой впереди, просто для безопасности:

;(function() {

}());

Лично я предпочитаю какой-нибудь оператор, например, bang (!):

!function () {

}();

С этим у вас нет проблем, которые вы имеете, используя скобки. Меньше характеров, и дает мне смысл "исполнения". Но, как и другой подход, это хак, и это вопрос личного вкуса. Например, Крокфорду очень не нравится вся эта шумиха.

Я предпочитаю pattern one, так как при определении функций как свойств объектов ваш синтаксис и становится очень многословным. Паттерн №1 прост в следовании; вы определяете функцию и затем вызываете ее. Шаблон 3 делает то же самое, но с дополнительным набором (), чтобы следовать. На мой взгляд, такая многословность имеет свою цену продуктивности.

Как вы сказали, все они верны, но я считаю важным помнить "бритву Оккама" = > когда все вещи равны, более простое объяснение (выражение) лучше, чем более сложный.

Все они прекрасно работают, вы можете использовать любой из них, рекомендуемый шаблон Crockford , хотя это шаблон №2:

var global = (function () {
   return this;
}());

Лично я нахожу паттерн #3 легким для работы, хотя, поскольку ему легко следовать:

var global = (function () {
    return this;
})();

Кстати, есть и другие шаблоны / сокращения, которые используют !, +, символы etc:

! function(){
  return this;
}();