IIFE (immediately invoked function expression) - функція, яку оголошують і одразу викликають:
(function () {
const secret = 'видно лише тут';
// ...
})();
(() => {
// те саме стрілковою функцією
})();
Дужки навколо функції потрібні, щоб рушій сприйняв її як вираз, а не як оголошення функції (яке не можна одразу викликати).
Навіщо їх використовували:
- ізоляція області видимості. До ES-модулів усі скрипти на сторінці ділили одну глобальну область. Змінні з
varна верхньому рівні ставали властивостямиwindowі конфліктували між бібліотеками. IIFE створювала приватну область; - шаблон «модуль» - приватний стан плюс публічний інтерфейс:
const counter = (function () {
let count = 0;
return {
increment: () => ++count,
current: () => count,
};
})();
- копія значення в циклі з
var- до появиletкожна ітерація ділила одну змінну.
Що змінилося:
- ES-модулі мають власну область видимості: змінні верхнього рівня модуля не глобальні. Vite, вбудовані
<script type="module">- IIFE для ізоляції не потрібні; letіconstмають блокову область видимості - досить фігурних дужок;- замикання для приватного стану тепер часто замінюють приватні поля класів (
#count).
Де IIFE досі трапляються:
- асинхронний код на верхньому рівні звичайного скрипта (не модуля), де немає top-level
await:
(async () => {
const config = await loadConfig();
start(config);
})();
- результат збирання. Збирачі пакують код для старих оточень і бібліотеки у формат IIFE (наприклад,
format: 'iife'у Rollup/Vite) - так вони підключаються одним<script>без конфліктів; - ініціалізація константи складною логікою в одному виразі (хоча зазвичай читабельніша окрема функція).
Пастка: рядок перед IIFE без крапки з комою. const a = b і на наступному рядку (function () {})() рушій прочитає як виклик b(...). Звідси звичка ставити ; перед IIFE у коді без крапок з комою.