Замыкания в JavaScript: что такое closure в JS

Замыкание (closure) — это функция, которая запоминает свою область видимости даже после выхода из нее. Это позволяет функции получать доступ к переменным из внешней области, даже если эта область больше не существует.

Простой пример замыкания

function createGreeting(name) {
    let greeting = `Привет, ${name}!`;

    return function () {
        console.log(greeting);
    };
}

const greetJohn = createGreeting('Иван');
greetJohn(); // 'Привет, Иван!'

Функция createGreeting замыкает в себе переменную greeting, даже когда ее внешний контекст завершил выполнение.

Как работают замыкания

При каждом вызове функции создается новая область видимости. Если внутренняя функция ссылается на переменные из внешней функции, они сохраняются в памяти и остаются доступными.

Пример счетчика с замыканием

function generateID() {
    let id = 0;

    return function () {
        id++;
        console.log(`Ваш уникальный ID: ${id}`);
    };
}

const getNextID = generateID();

getNextID(); // 'Ваш уникальный ID: 1'
getNextID(); // 'Ваш уникальный ID: 2'
getNextID(); // 'Ваш уникальный ID: 3'

Переменная id остается в памяти, так как внутренняя функция продолжает ее использовать.

Использование замыканий

1. Создание приватных переменных

Замыкания позволяют делать переменные недоступными извне.

function secretCodeGenerator(secret) {
    return {
        reveal() {
            console.log(`Секретный код: ${secret}`);
        },
        updateCode(newSecret) {
            secret = newSecret;
        }
    };
}

const secretCode = secretCodeGenerator('ABC123');

secretCode.reveal(); // 'Секретный код: ABC123'
secretCode.updateCode('XYZ789');
secretCode.reveal(); // 'Секретный код: XYZ789'

2. Использование в обработчиках событий

function createLogger(prefix) {
    return function (message) {
        console.log(`[${prefix}] ${message}`);
    };
}

const errorLogger = createLogger('Ошибка');
errorLogger('Сервер недоступен'); // '[Ошибка] Сервер недоступен'

const debugLogger = createLogger('Отладка');
debugLogger('Запуск процесса'); // '[Отладка] Запуск процесса'

3. Генерация функций с разными параметрами

function createTaxCalculator(taxRate) {
    return function (amount) {
        return amount + (amount * taxRate);
    };
}

const taxInUSA = createTaxCalculator(0.1);
console.log(taxInUSA(100)); // 110

const taxInEurope = createTaxCalculator(0.2);
console.log(taxInEurope(100)); // 120

Важно учитывать

  1. Замыкания удерживают в памяти переменные, которые используются во внутренней функции.
    Если замыкания создаются в циклах или часто вызываются, это может привести к утечке памяти.
  2. Замыкания хранятся в памяти, пока есть ссылка на внутреннюю функцию.
    Если переменная больше не используется, сборщик мусора удалит замыкание.

Замыкания в JavaScript — это мощный механизм, позволяющий работать с приватными переменными, создавать фабрики функций и сохранять состояние между вызовами. Они активно используются в программировании, особенно в обработчиках событий, таймерах, модулях и функциональном программировании