Самовызывающиеся функции (IIFE — Immediately Invoked Function Expression) — это функции, которые выполняются сразу после их объявления. Они создают изолированную область видимости и не загрязняют глобальное пространство имён.
Основные преимущества:
Самовызывающиеся функции (IIFE) — это паттерн в JavaScript, при котором функция объявляется и сразу же выполняется. Это позволяет создать изолированную область видимости.
// Обычная функция
function sayHello() {
console.log("Привет!");
}
sayHello(); // Нужно вызвать отдельно
// Самовызывающаяся функция
(function() {
console.log("Привет!");
})(); // Выполняется сразу
(function() {
console.log("Выполняется сразу!");
})();
(function() {
console.log("Тоже работает!");
}());
(function(name, age) {
console.log(`Привет, ${name}! Тебе ${age} лет.`);
})("Александр", 30);
(() => {
console.log("IIFE со стрелочной функцией!");
})();
// С параметрами
((name) => {
console.log(`Привет, ${name}!`);
})("Мария");
const result = (function(a, b) {
return a + b;
})(5, 3);
console.log(result); // 8
// ❌ Проблема — переменные в глобальной области
var userName = "Александр";
var userAge = 30;
function showUser() {
console.log(userName, userAge);
}
// ✅ Решение — изоляция с IIFE
(function() {
var userName = "Александр";
var userAge = 30;
function showUser() {
console.log(userName, userAge);
}
showUser(); // Работает только внутри IIFE
})();
// console.log(userName); // ReferenceError
// Библиотека A
(function() {
var utils = {
format: function(text) {
return text.toUpperCase();
}
};
// Используем utils только здесь
})();
// Библиотека B
(function() {
var utils = {
format: function(text) {
return text.toLowerCase();
}
};
// Свой utils, без конфликтов
})();
(function() {
// Настройка при загрузке страницы
const config = {
apiUrl: "https://api.example.com",
timeout: 5000
};
function initApp() {
console.log("Приложение запущено!");
console.log("API URL:", config.apiUrl);
}
// Запускаем сразу
initApp();
})();
const Calculator = (function() {
// Приватные переменные
let result = 0;
// Приватные функции
function log(operation, value) {
console.log(`${operation}: ${value}`);
}
// Публичный API
return {
add: function(num) {
result += num;
log("Сложение", result);
return this;
},
multiply: function(num) {
result *= num;
log("Умножение", result);
return this;
},
getResult: function() {
return result;
},
reset: function() {
result = 0;
log("Сброс", result);
return this;
}
};
})();
// Использование
Calculator.add(5).multiply(2).add(3);
console.log(Calculator.getResult()); // 13
const counter = (function() {
let count = 0;
return {
increment: function() {
count++;
return count;
},
decrement: function() {
count--;
return count;
},
getValue: function() {
return count;
}
};
})();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getValue()); // 2
// console.log(count); // ReferenceError — count недоступен
const AppConfig = (function() {
const settings = {
theme: "dark",
language: "ru",
apiUrl: "https://api.example.com"
};
return {
get: function(key) {
return settings[key];
},
set: function(key, value) {
if (settings.hasOwnProperty(key)) {
settings[key] = value;
}
},
getAll: function() {
return { ...settings }; // Копия, не оригинал
}
};
})();
// Использование
console.log(AppConfig.get("theme")); // "dark"
AppConfig.set("theme", "light");
console.log(AppConfig.get("theme")); // "light"
var x = 10;
(function() {
var x = 20;
console.log(x);
})();
console.log(x);
const module = (function(initial) {
let value = initial;
return {
getValue: () => value,
setValue: (newValue) => { value = newValue; }
};
})(100);
module.setValue(200);
console.log(module.getValue());
console.log(value);
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, 100);
}
// Исправьте с помощью IIFE
for (var i = 0; i < 3; i++) {
(function(index) {
setTimeout(function() {
console.log(index);
}, 100);
})(i);
}
Выведет: 0, 1, 2
// Вместо IIFE для модулей
// module.js
let count = 0;
export function increment() {
return ++count;
}
export function getCount() {
return count;
}
// main.js
import { increment, getCount } from './module.js';
// Вместо IIFE для изоляции
{
let userName = "Александр";
const userAge = 30;
console.log(userName, userAge);
}
// console.log(userName); // ReferenceError
// Для асинхронного кода
(async function() {
try {
const response = await fetch('/api/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Ошибка:', error);
}
})();
// 1. Создание модулей (до ES6)
const MyModule = (function() {
// приватный код
return { /* публичный API */ };
})();
// 2. Инициализация при загрузке
(function() {
document.addEventListener('DOMContentLoaded', function() {
console.log('Страница загружена!');
});
})();
// 3. Изоляция библиотек
(function($, window, document) {
// Код плагина
})(jQuery, window, document);
// 4. Конфигурация
const Config = (function() {
const settings = { /* настройки */ };
return { /* методы доступа */ };
})();
// ❌ Простые вычисления
(function() {
return 2 + 2;
})(); // Лучше просто: 2 + 2
// ❌ Современные модули
// Используйте ES6 import/export
// ❌ Блочная область видимости
// Используйте let/const в блоках {}
// ❌ Ошибка — функция не вызывается
function() {
console.log("Не работает!");
};
// ✅ Правильно
(function() {
console.log("Работает!");
})();
// ❌ Ошибка синтаксиса
(function() {
console.log("Привет!");
}); // Забыли вызвать
// ✅ Правильно
(function() {
console.log("Привет!");
})(); // Вызываем сразу
const obj = {
name: "Александр",
init: function() {
// ❌ Потеря this в IIFE
(function() {
console.log(this.name); // undefined
})();
// ✅ Сохранение this
const self = this;
(function() {
console.log(self.name); // "Александр"
})();
// ✅ Стрелочная функция
(() => {
console.log(this.name); // "Александр"
})();
}
};
Самовызывающиеся функции (IIFE) — это важный паттерн JavaScript, который:
Преимущества:
Применение:
Синтаксис:
(function() {
// код
})();
// или
(() => {
// код
})();
Понимание IIFE поможет вам писать чистый и модульный код без загрязнения глобального пространства имён!
Хочешь больше статей по подготовке к собеседованию? Подпишись на EasyAdvice(@AleksandrEmolov_EasyAdvice), добавляй сайт в избранное и прокачивай себя каждый день 💪