Что такое IIFE и зачем этот паттерн используется?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
IIFE (Immediately Invoked Function Expression) и его использование
IIFE — один из самых старых и полезных паттернов в JavaScript. Несмотря на появление ES6 модулей и других инструментов, IIFE остаётся актуальным паттерном.
Определение IIFE
IIFE (Immediately Invoked Function Expression) — это функция, которая определяется и сразу же вызывается в момент объявления.
// Базовый синтаксис
(function() {
console.log("Это выполняется сразу!");
})();
// Или с параметрами
(function(name) {
console.log("Привет, " + name);
})("World");
// Или с стрелочной функцией
(() => {
console.log("Стрелочная IIFE");
})();
Основные причины использования IIFE
1. Создание локального scope (изоляция переменных)
В старом JavaScript (до ES6) не было let и const. Единственный способ создать локальный scope — это функция.
// ❌ Плохо: переменные глобальны
var x = "глобальная переменная";
var y = "ещё одна глобальная";
// ✓ Хорошо: IIFE создаёт новый scope
(function() {
var x = "локальная переменная";
var y = "ещё одна локальная";
})();
console.log(typeof x); // undefined
Это критично было в старом коде jQuery плагинов:
(function($) {
$.fn.myPlugin = function() {
// $ теперь локален, не конфликтует
};
})(jQuery);
2. Избегание загрязнения глобального namespace
// ❌ Плохо: загрязняем глобальный scope
window.userUtils = {};
window.config = {};
// ✓ Хорошо: IIFE изолирует код
(function() {
const userUtils = { ... };
const config = { ... };
// Только нужное экспортируем
window.MyApp = window.MyApp || {};
window.MyApp.userUtils = userUtils;
})();
3. Модульный паттерн (Module Pattern)
Это мощное применение IIFE для создания приватных переменных:
const counterModule = (function() {
let count = 0; // приватная переменная
return {
increment: function() {
count++;
return count;
},
decrement: function() {
count--;
return count;
},
getCount: function() {
return count;
}
};
})();
console.log(counterModule.increment()); // 1
console.log(counterModule.getCount()); // 1
// count НЕ доступна напрямую
console.log(counterModule.count); // undefined
Это паттерн закрытия (closure) + IIFE. Очень полезно для создания приватных данных!
4. Создание приватных функций-помощников
const DataProcessor = (function() {
// Приватная функция
function validateData(data) {
if (!data || data.length === 0) {
throw new Error("Data is empty");
}
return true;
}
// Публичный API
return {
processData: function(rawData) {
validateData(rawData);
return rawData.map(item => ({
...item,
processed: true
}));
}
};
})();
DataProcessor.processData([1, 2, 3]); // работает
DataProcessor.validateData([]); // undefined - не доступна
5. Передача внешних переменных для быстродействия
// Параметры document и window это локальные ссылки
// поиск в глобальном scope медленнее
(function(window, document) {
const element = document.getElementById("my-id");
// document поиск будет быстрее
})(window, document);
6. Инициализация при загрузке страницы
(function() {
const scripts = document.querySelectorAll("script[data-init]");
scripts.forEach(script => {
const module = script.getAttribute("data-init");
console.log(`Инициализация ${module}`);
});
})();
// Остальной код выполняется после
Когда НЕ нужна IIFE в современном JavaScript
С ES6 много применений IIFE стали ненужными:
// ✗ Старый способ (IIFE)
(function() {
var x = "локальный";
})();
// ✓ Современный способ (блоковый scope)
{
let x = "локальный";
}
console.log(typeof x); // undefined
// ✓ ES6 модули
export const myFunction = () => {};
const privateVariable = "приватная";
Практические примеры
Пример 1: Polyfill
(function() {
if (!Array.prototype.includes) {
Array.prototype.includes = function(item) {
return this.indexOf(item) !== -1;
};
}
})();
Пример 2: Инициализация приложения
(function(app) {
const config = {
apiUrl: "https://api.example.com",
timeout: 5000
};
const api = {
get: async (url) => {
return fetch(app.config.apiUrl + url);
}
};
app.config = config;
app.api = api;
})(window.App = window.App || {});
window.App.api.get("/users");
IIFE в Node.js
В Node.js IIFE используется реже потому что ES6 модули нативны:
// Инициализация сервера
(async () => {
const app = express();
const db = await connectToDatabase();
app.listen(3000);
})();
Главный вывод
IIFE — паттерн, который был очень важен в старом JavaScript, когда не было модулей. Сейчас его основное применение:
- Модульный паттерн для создания приватных данных
- Изоляция кода в браузере
- Инициализация при загрузке
- Избегание глобального namespace
В современном JavaScript с ES6 модулями, IIFE менее актуален, но остаётся полезным паттерном для некоторых сценариев.