Этот код возвращает ошибку маркера:
function foo(){ }(); // Error: Unexpected token ')'
Parens
Если мы поместим выражение внутрь второго парена (оператор группировки, который ожидает, что будет оценено выражение), ошибка исчезнет.
function foo(){ }(1);
Итак, мы знаем, что ошибка с маркером связана со вторым паренсом, в котором не было никакого выражения для оценки.
Но… это все еще не работает как IIFE.
Разбивка
Давайте изменим foo()
для записи в журнал приветствия. Как видите, в консоль ничего не записывается.
function foo(){ console.log('Hello from foo!') }(1); // Nothing logged to the console
Это происходит потому, что foo()
никогда не вызывается.
На самом деле, мы ошибаемся, ожидая, что foo()
будет вызван таким образом:
function foo(){ console.log('Hello from foo!') }();
Потому что вторая паренс здесь не означает вызов foo()
. И это потому, что объявление функции, оставленное после нее, function foo(){ }
, не является выражением. Это просто определение.
Парсер воспринимает приведенный выше код как:
function foo(){ console.log('Hello from foo!') };
();
Исправьте
Для того чтобы второе паренс (сразу) вызвало foo()
, нам нужно, чтобы объявление функции сначала было оценено в выражение функции. И знаете что, мы делаем это с помощью второго парена.
(function foo(){ console.log('Hello from foo!') });
Затем мы можем применить паренс вызова:
(function foo(){ console.log('Hello from foo!') }(); // "Hello from foo!"
Другим исправлением может быть обертывание всего кода в общий паренс. Это также заставит его работать как IIFE:
(function foo(){ console.log('Hello from foo!') }()); // "Hello from foo!"
Здесь все, включая последние парены, считается частью одного выражения, и поэтому вызывается foo()
.
Ссылки
- Немедленно вызываемое функциональное выражение (IIFE)
- IIFE