Сразу вызываемое выражение функции - Immediately invoked function expression

An немедленно вызванное выражение функции (или же IIFE, произносится как "сомнительный", IPA /ˈꞮf.i/)[1] это JavaScript идиома языка программирования который производит лексическая область используя JavaScript область видимости функции.

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

использование

Сразу вызываемые функциональные выражения могут быть записаны разными способами.[2] А общее соглашение состоит в том, чтобы заключить выражение функции - и, возможно, его оператор вызова - с оператором группировки,[3] в скобках, чтобы явно указать синтаксическому анализатору ожидать выражения. В противном случае в большинстве ситуаций, когда парсер обнаруживает функция ключевое слово, оно рассматривает его как объявление функции (оператор), а не как выражение функции.[4][5]

(функция () { /* ... */ })();(функция () { /* ... */ }());(() => { /* ... */ })(); // Со стрелочными функциями ES6 (хотя круглые скобки разрешены только снаружи)

Есть и другие способы принудительного выполнения выражения функции:

!функция () { /* ... */ }();~функция () { /* ... */ }();-функция () { /* ... */ }();+функция () { /* ... */ }();пустота функция () { /* ... */ }();

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

вар ж = функция () { /* ... */ }();истинный && функция () { /* ... */ }();0, функция () { /* ... */ }();

Передача переменных в область видимости выполняется следующим образом:

(функция(а, б) { /* ... */ })("Привет", "Мир");

Начальная скобка - это тот случай, когда автоматическая вставка точки с запятой (ASI) в JavaScript может вызвать проблемы; выражение вместо этого интерпретируется как вызов последнего термина в предыдущей строке. В некоторых стилях, которые опускают необязательные точки с запятой, точка с запятой ставится спереди круглой скобки и известен как защитная точка с запятой.[6][7] Например:

а = б + c;(функция () {  // код})();

... чтобы избежать синтаксического анализа как c ().

Примеры

Ключом к пониманию шаблонов проектирования, таких как IIFE, является осознание того, что до ES6 в JavaScript использовался только объем функции (таким образом, не хватает область действия блока ), проходя значения по ссылке внутри закрытие.[8] Это уже не так, поскольку версия JavaScript для ES6 реализует область видимости блока с использованием нового позволять и const ключевые слова.[9]

Контекст оценки

Отсутствие области видимости блока означает, что переменные, определенные внутри (например) для цикла будет иметь их определение «поднятым» на вершину включающей функции. Оценка функции, которая зависит от переменных, измененных внешней функцией (в том числе путем итерации), может быть трудной. Мы можем увидеть это без цикла, если обновим значение между определением и вызовом функции.[10]

вар v, getValue;v = 1;getValue = функция () { возвращаться v; };v = 2;getValue(); // 2

Хотя результат может показаться очевидным при обновлении v вручную, это может привести к непредвиденным результатам, когда getValue () определяется внутри цикла.

Далее функция проходит v в качестве аргумента и вызывается немедленно, сохраняя контекст выполнения внутренней функции.[11]

вар v, getValue;v = 1;getValue = (функция (Икс) {    возвращаться функция () { возвращаться Икс; };})(v);v = 2;getValue();  // 1

Это эквивалентно следующему коду:

вар v, getValue;v = 1;функция ж(Икс) {    возвращаться функция () { возвращаться Икс; };};getValue = ж(v);v = 2;getValue();  // 1

Дэвида Хермана Эффективный JavaScript содержит пример, иллюстрирующий проблемы оценки контекста внутри циклов.[12] Хотя пример Германа намеренно запутан, он напрямую связан с тем же недостатком области видимости блока.[13]

Создание частных переменных и методов доступа

IIFE также полезны для создания частных методов для доступных функций, в то же время предоставляя некоторые свойства для последующего использования.[14] Следующий пример взят из сообщения Алмана о IIFE.[1]

// «счетчик» - это функция, которая возвращает объект со свойствами, которые в данном случае являются функциями.вар прилавок = (функция () {    вар я = 0;    возвращаться {        получать: функция () {            возвращаться я;        },        набор: функция (вал) {            я = вал;        },        приращение: функция () {            возвращаться ++я;        }    };})();// Эти вызовы обращаются к свойствам функции, возвращаемым "counter".прилавок.получать();       // 0прилавок.набор(3);прилавок.приращение(); // 4прилавок.приращение(); // 5

Если мы попытаемся получить доступ counter.i из глобальной среды он будет неопределенным, так как он заключен в вызванную функцию и не является свойством прилавок. Аналогичным образом, если мы попытаемся получить доступ я, это приведет к ошибке, поскольку мы не объявили я в глобальной среде.

Терминология

Первоначально известная как «самоисполняющаяся анонимная функция»,[15] Бен Альман позже представил текущий термин IIFE как более семантически точное название идиомы, вскоре после того, как его обсуждение возникло на comp.lang.javascript.[1][16][17]

Примечательно, что немедленно вызываемые функции не обязательно должны быть анонимными по сути, и ECMAScript Строгий режим 5 запрещает arguments.callee,[18] перевод оригинального термина неправильное употребление.

Смотрите также

Рекомендации

  1. ^ а б c Алман, Бен (15 ноября 2010 г.). «Сразу вызываемые функциональные выражения». В архиве с оригинала на 1 декабря 2017 г.. Получено 18 января 2019.
  2. ^ Линдли, Коди (2013). Просвещение JavaScript. О'Рейли. п. 61. ISBN  978-1-4493-4288-3.
  3. ^ «Оператор группировки». Сеть разработчиков Mozilla.
  4. ^ Закас, Николас (2012). Поддерживаемый JavaScript. О'Рейли. п. 44. ISBN  978-1-4493-2768-2.
  5. ^ Аксель Раушмайер. "Изучение JS".
  6. ^ «Вставка точки с запятой в JavaScript: все, что вам нужно знать». 28 мая 2010 г. В архиве из оригинала 2 октября 2017 года.
  7. ^ Марохнич, Мислав (7 мая 2010 г.). «Точка с запятой в JavaScript не обязательна». В архиве из оригинала от 8 августа 2017 года.
  8. ^ Хавербеке, Марин (2011). Красноречивый JavaScript. Пресс без крахмала. С. 29–30. ISBN  978-1-59327-282-1.
  9. ^ ECMAScript 6: Новые возможности: обзор и сравнение, Переменные с блочной областью видимости
  10. ^ Алман, Бен. "simple-iife-example.js". Github. Получено 5 февраля 2013.
  11. ^ Отеро, Сезар; Ларсен, Роб (2012). Профессиональный jQuery. Джон Вили и сыновья. п. 31. ISBN  978-1-118-22211-9.
  12. ^ Герман, Дэвид (2012). Эффективный Javascript. Эддисон-Уэсли. С. 44–45. ISBN  978-0-321-81218-6.
  13. ^ Закас, Николас С. (2011). «Подражание блоку». Профессиональный JavaScript для веб-разработчиков. Джон Вили и сыновья. ISBN  978-1-118-23309-2.
  14. ^ Реттиг, Паскаль (2012). Профессиональная разработка мобильных игр на HTML5. Джон Вили и сыновья. п. 145. ISBN  978-1-118-30133-3.
  15. ^ Resig, Джон (2006). Профессиональные методы JavaScript. Апресс. п. 29. ISBN  978-1-4302-0283-7.
  16. ^ Османи, Адди (2012). Изучение шаблонов проектирования JavaScript. О'Рейли. п. 206. ISBN  978-1-4493-3487-1.
  17. ^ Баагое, Йоханнес. «Закрывающая скобка в определении функции с последующим ее вызовом». Получено 19 апреля 2010.
  18. ^ «Строгий режим». Справочник Mozilla JavaScript. Сеть разработчиков Mozilla. Получено 4 февраля 2013.

внешняя ссылка