> Пример замыкания с внутренней функцией и предмет замыкания в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Кэтрид Диджитал
Стек: JavaScript
> Пример ответа
Короткий ответ
Замыкание - это комбинация функции и лексического окружения, в котором она была объявлена. Внутренняя функция "замыкает" переменные внешней функции даже после завершения её выполнения. Предмет замыкания - доступ к переменным внешней области видимости, которые не уничтожаются сборщиком мусора, пока существует внутренняя функция.
Подробное объяснение
В JavaScript каждая функция при создании получает скрытое свойство [[Environment]], которое ссылается на текущее лексическое окружение. Когда внутренняя функция вызывается позже, она ищет переменные сначала в своём окружении, затем в окружении, на которое ссылается [[Environment]], и так далее по цепочке.
Ключевой момент: внешняя функция завершила выполнение, её локальные переменные обычно удаляются, но если внутренняя функция остаётся доступной, эти переменные сохраняются в памяти. Именно это сохранение и есть замыкание.
Предмет замыкания - не просто доступ к переменным, а именно сохранение их состояния между вызовами. Это позволяет создавать приватные данные, фабрики функций, частичное применение аргументов и мемоизацию.
На практике
Замыкания широко используются в реальном коде:
- модульный паттерн для инкапсуляции состояния
- обработчики событий, которым нужен доступ к данным на момент создания
- счётчики, генераторы уникальных id
- функции-фабрики, создающие функции с предзаданными параметрами
- мемоизация - кэширование результатов дорогих вычислений
Важно понимать, что замыкание захватывает не значение переменной, а саму переменную (ссылку на неё). Поэтому если переменная меняется, внутренняя функция увидит новое значение.
Пример кода
JAVASCRIPTfunction createCounter() {let count = 0; // переменная из внешней области видимостиreturn function() {count += 1; // внутренняя функция замыкает countreturn count;};}const counter = createCounter();console.log(counter()); // 1console.log(counter()); // 2console.log(counter()); // 3
Ещё пример с захватом переменной, а не значения:
JAVASCRIPTfunction createFunctions() {const funcs = [];for (var i = 0; i < 3; i++) {funcs.push(function() {return i;});}return funcs;}const funcs = createFunctions();console.log(funcs[0]()); // 3, а не 0 - все функции замыкают одну и ту же переменную i
Как отвечать на собеседовании
Начни с определения: замыкание - это функция вместе с её лексическим окружением. Затем объясни механизм: внутренняя функция сохраняет ссылку на окружение внешней, поэтому переменные не удаляются. Приведи пример с счётчиком. Подчеркни, что замыкание захватывает переменную, а не её значение - это часто проверяют отдельно. Упомяни практическое применение: инкапсуляция, фабрики, мемоизация. Если спросят про var в цикле - объясни проблему и решение через let или IIFE.
Что проверяет интервьюер
Интервьюер проверяет:
- понимание лексической области видимости и цепочки областей видимости
- знание механизма
[[Environment]]и работы сборщика мусора - умение объяснить разницу между захватом значения и захватом ссылки
- способность применить замыкания на практике, а не только дать определение
- понимание связи замыканий с памятью и потенциальными утечками
Типичные ошибки
- утверждение, что замыкание - это просто вложенная функция (это необходимое, но не достаточное условие)
- путаница между замыканием и областью видимости
- непонимание, что замыкание захватывает переменную, а не её текущее значение
- забывание про утечки памяти: если замыкание хранится долго, оно удерживает всё окружение
- неумение объяснить поведение
varв цикле с замыканиями - попытка объяснить через "копирование значений" - это неверно, происходит захват ссылки
> Похожие задачи по frontend
Какие способы есть для итерации по объекту в JavaScript кроме for-in
Чем собственные свойства отличаются от унаследованных в JavaScript
Для чего нужен оператор nullish coalescing (??) и как он работает в JavaScript
Как обращаться к объекту массива через this в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью