← Назад к вопросам

Что такое IIFE и зачем этот паттерн используется?

1.0 Junior🔥 111 комментариев
#Node.js и JavaScript#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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 менее актуален, но остаётся полезным паттерном для некоторых сценариев.