IIFE, функція, що викликає сама себе
IIFE (Immediately Invoked Function Expression) це функція, яка створюється і викликається одразу ж, без окремого виклику за іменем. Її класична задача це отримати власну область видимості й не залишити по собі зайвих глобальних змінних.
Теорія
TL;DR
- IIFE це функціональний вираз, який викликається в тому ж місці, де його оголошено.
- Перша пара дужок перетворює функцію на вираз, друга пара її викликає.
- Тіло IIFE має власний scope, тому змінні всередині не «забруднюють» глобальний об'єкт (
windowабоglobal). - Типові застосування: одноразова ініціалізація, приховані тимчасові змінні, повернення готового конфігу.
- Асинхронна IIFE
(async () => { ... })()дає змогу використатиawaitтам, де немає top-level await. - З появою модулів ES6 потреба в IIFE зменшилась, бо кожен модуль і так має свою область видимості.
Швидкий приклад
(function () {
console.log('Виконалось одразу після оголошення');
})();Як працює синтаксис
Зверніть увагу на дві пари дужок:
- Перша,
(function () { ... }), перетворює функцію на функціональний вираз. Без неї рушій прочитав би рядок як оголошення функції, а оголошення не можна викликати на місці. - Друга,
(), негайно викликає цей вираз.
IIFE приймає аргументи так само, як звичайна функція:
(function (name) {
console.log(`Привіт, ${name}!`);
})('Maria');Виведе:
Привіт, Maria!Той самий запис зі стрілковою функцією коротший, і його теж часто називають IIFE:
(() => {
console.log('Стрілкова IIFE');
})();Навіщо потрібна IIFE
1. Ізольована область видимості. IIFE часто застосовують, щоб уникнути конфліктів імен і не «забруднювати» глобальну область:
(function () {
const secret = 'Значення живе лише всередині функції';
console.log(secret);
})();
console.log(secret); // ReferenceError: secret is not definedЗмінна secret доступна тільки всередині IIFE.
2. Одноразова ініціалізація. IIFE зручна, щоб щось порахувати один раз під час завантаження і віддати назовні лише результат:
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):
(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, там окрема область видимості не потрібна.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.