Первый пример - это присваивание: правая часть является выражением, и немедленное выполнение анонимной функции имеет смысл.
Второй пример - объявление : как только закрывается "}", объявление заканчивается. Пары сами по себе не имеют смысла - они должны содержать выражение. Конечная ")" является ошибкой.
Автономные объявления должны быть преобразованы в выражения:
(function() {})(); // Or...
(function() {}());
Первое делает объявление выражением, а затем выполняет результат. Второй превращает оба объявления и выполнение в выражение.
Вы можете (function(){})();, и вы не называете функцию в: var foo = function(){}();
Вы устанавливаете foo в возвращаемое значение функции, которая в вашем случае undefined, потому что все функции возвращают что-то в JavaScript.
Ответ 3
Первое использование функции
var foo = function(){}()
находится в позиции выражения, а не в позиции оператора. Второй, с другой стороны, находится на верхнем уровне и работает как оператор функции. То есть, "функция" может использоваться в двух разных контекстах, и это может означать несколько разные вещи.
Если вы хотите сделать анонимные функции без имен, вы делаете это с помощью выражения функции. И только из-за того, как работает грамматика языка JavaScript, вам понадобятся парсеры в определенном контексте, как упоминает Дейв Ньютон, потому что место, где вы помещаете слово "функция", можно путать со своей версией оператора (что требует имя).