Skip to main content

IIFE, функція, що викликає сама себе

IIFE (Immediately Invoked Function Expression) це функція, яка створюється і викликається одразу ж, без окремого виклику за іменем. Її класична задача це отримати власну область видимості й не залишити по собі зайвих глобальних змінних.

Теорія

TL;DR

  • IIFE це функціональний вираз, який викликається в тому ж місці, де його оголошено.
  • Перша пара дужок перетворює функцію на вираз, друга пара її викликає.
  • Тіло IIFE має власний scope, тому змінні всередині не «забруднюють» глобальний об'єкт (window або global).
  • Типові застосування: одноразова ініціалізація, приховані тимчасові змінні, повернення готового конфігу.
  • Асинхронна IIFE (async () => { ... })() дає змогу використати await там, де немає top-level await.
  • З появою модулів ES6 потреба в IIFE зменшилась, бо кожен модуль і так має свою область видимості.

Швидкий приклад

javascript
(function () { console.log('Виконалось одразу після оголошення'); })();

Як працює синтаксис

Зверніть увагу на дві пари дужок:

  1. Перша, (function () { ... }), перетворює функцію на функціональний вираз. Без неї рушій прочитав би рядок як оголошення функції, а оголошення не можна викликати на місці.
  2. Друга, (), негайно викликає цей вираз.

IIFE приймає аргументи так само, як звичайна функція:

javascript
(function (name) { console.log(`Привіт, ${name}!`); })('Maria');

Виведе:

text
Привіт, Maria!

Той самий запис зі стрілковою функцією коротший, і його теж часто називають IIFE:

javascript
(() => { console.log('Стрілкова IIFE'); })();

Навіщо потрібна IIFE

1. Ізольована область видимості. IIFE часто застосовують, щоб уникнути конфліктів імен і не «забруднювати» глобальну область:

javascript
(function () { const secret = 'Значення живе лише всередині функції'; console.log(secret); })(); console.log(secret); // ReferenceError: secret is not defined

Змінна secret доступна тільки всередині IIFE.

2. Одноразова ініціалізація. IIFE зручна, щоб щось порахувати один раз під час завантаження і віддати назовні лише результат:

javascript
const config = (() => { const apiKey = '12345'; const baseUrl = 'https://api.example.com'; return { apiKey, baseUrl }; })(); console.log(config.apiKey); // 12345

Назовні повертається об'єкт, а проміжні змінні залишаються інкапсульованими.

3. Асинхронний код на верхньому рівні. IIFE можна зробити асинхронною і використати await там, де top-level await недоступний (наприклад, у звичайному скрипті або в CommonJS):

javascript
(async () => { const data = await fetch('/api/data').then((res) => res.json()); console.log(data); })();

IIFE і сучасні модулі

До появи модулів ES6 IIFE була основним інструментом інкапсуляції та структурування коду: саме на ній будувався патерн «module pattern». Тепер кожен файл із import або export і так має власну область видимості, тому IIFE використовують рідше. Вона й далі корисна для:

  • одноразової ініціалізації,
  • ізоляції тимчасових змінних у великій функції чи скрипті,
  • негайного запуску асинхронного коду.

Коротко:

ХарактеристикаОпис
НазваIIFE, Immediately Invoked Function Expression
СутьФункція створюється і тут же викликається
НавіщоІзоляція, ініціалізація, тимчасові змінні
ОсобливостіНе забруднює глобальну область, може бути async

Типові помилки

  • Забути зовнішні дужки: function () {}() у позиції оголошення дасть синтаксичну помилку.
  • Не поставити крапку з комою в кінці попереднього рядка: рядок, що починається з (, «приклеїться» до попереднього виразу і буде прочитаний як виклик.
  • Очікувати, що var усередині IIFE стане глобальним: він залишиться локальним, і саме в цьому сенс IIFE.
  • Думати, що асинхронна IIFE блокує виконання: вона повертає проміс, і код після неї виконується далі, тому помилки варто ловити через .catch() або try/catch усередині.
  • Писати IIFE у коді, який уже є модулем ES6, там окрема область видимості не потрібна.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.