В Javascript IIFE обозначает выражение с немедленным вызовом функции: выражение функции, которое вызывается сразу после его определения, например (function(){ /* code */ })();

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

(function() { /* code */ })();

Но есть несколько других допустимых способов формирования IIFE, упомянутых в этом ответе, например

(function() { /* code */ }());
new function(){ /* code */ }();

Термин IIFE был впервые предложен Беном Альманом в этой статье, в которой он предлагает произношение "сомнительный". Он предложил этот термин в качестве альтернативы тому, что он называет "популярным, но вводящим в заблуждение термином самоисполняющаяся анонимная функция".

Наиболее распространенные обозначения, используемые сегодня: (function(){}());, с вызывающими круглыми скобками внутри группировки (), а также (function(){})();, с вызывающими скобками вне группы.

Помимо незначительной семантической разницы между ними (первый оценивается как (returnvalue of IIFE), а второй оценивается как (defined function)<=(call)) они оба одинаково верны, хотя известный эксперт по JavaScript Дуглас Крокфорд считает вторую нотацию "неправильной" и "нелогичной":

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

Из соглашений о коде для языка программирования JavaScript.

Термин IIFE был быстро принят сообществом после его первого появления в конце 2010 года. Просто потому, что это наиболее точное описание самого шаблона:

  • II (немедленно вызывается): функция определяется и вызывается за один раз. Это довольно ясно
  • F (Функция) Это функция...
  • E (выражение): Не просто какая-то старая функция: это скорее выражение, чем утверждение. Это очень важно.

Разница между определением функции и выражением функции заключается в том, где функция определяется (например, придерживаясь JavaScript).

// Any old function:
function f(arg)
{
    return arg;
}

Это определение функции будет поднято наверх своей области видимости и станет доступным во всей этой области:

console.log(f(123));
function f(n)
{
    return (typeof n);
}

аккуратно войдет number, хотя кажется, что функция вызывается до ее определения.

Превращая функцию в выражение, определение нельзя поднять:

console.log(typeof f);
var f = function()
{
    return 'something';
};
console.log(typeof f);

В этом примере единственное, что будет поднято, - это объявление переменной f. Само определение функции является выражением в форме правого операнда присваивания. Назначения никогда не поднимаются, поэтому код будет регистрироватьundefined, а потом function.

Чтобы превратить это Функциональное выражение в IIFE, мы должны сделать две вещи: Убедитесь, что определение функции является выражением, а не инструкцией. Как объяснялось выше, это достигается за счет включения функции в группировку() оператор или добавление логического или побитового оператора к оператору, void префикс или new ключевое слово.

Заметки:

Используя voidпрефикс эффективно подавляет возвращаемое значение IIFE и всегда возвращаетundefined:

var foo = void function()
{
    console.log('called');
    return 'returnVal';
};
console.log(foo);

Журналы called, а затем значение foo -> undefined.

Используя newключевое слово повлияет на контекст вызова (this ссылка) IIFE_: IIFE будет вести себя как конструктор, возвращая новый объект:

new function()
{
    return this.constructor;
};

вернет ссылку на только что вызванную функцию.

Конкретные варианты использования:

  • IFFE часто используются при передаче функции в качестве аргумента другой функции (особенно для решения печально известной проблемы цикла)
  • Пользовательские конструкторы часто заключаются в оболочку IIFE, что позволяет использовать псевдо (частные) статические свойства. Переменные, объявленные в области видимости IIFE, остаются в памяти до тех пор, пока где-то имеется ссылка на возвращаемое значение этого IIFE. Это возвращаемое значение может быть объектом с функцией, которая, в свою очередь, ссылается на переменные из области IIFE. Вот вам пример.
  • В некоторых браузерах, в частности, в более старых версиях InternetExplorer, присоединение обработчиков событий непосредственно к ссылкам DOM вызывало утечки памяти из-за того, что InternetExplorer управлял памятью для DOM и его механизма JScript отдельно. Единственный способ обойти это - присоединить слушателей к IIFE. Когда сценарий завершается, GC (сборщик мусора) может помечать и перемещать всю область IIFE, и вместе с ней все ссылки на DOM и обработчики событий освобождаются.
  • Для некоторых шаблонов, таких как шаблон модуля, требуется IIFE. В этой функции модуль создается и в конечном итоге отображается (путем присвоения глобальной переменной) или возвращается.
  • Иногда весь скрипт оборачивается IIFE, чтобы избежать глобальных переменных. Это, однако, считается быстрым и незамысловатым решением.