Что такое замыкания (closures) в JavaScript?

MiddleJavaScript #javascript #closures

Вопрос

Что такое замыкание в JavaScript и как оно работает?

Короткий ответ

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

Подробный ответ

Каждая функция в JavaScript "запоминает" окружение, в котором она была создана. Это происходит потому, что движок хранит ссылку на область видимости (scope), а не копирует значения переменных.

Замыкания используются для:

  • Инкапсуляции состояния — создания приватных переменных без классов.
  • Каррирования и фабрик функций.
  • Мемоизации и дебаунса/троттлинга — состояние живёт между вызовами.

Частая ошибка — замыкание в цикле с var, из-за отсутствия блочной области видимости все функции ссылаются на одну и ту же переменную.

Пример

function createCounter() {
  let count = 0
  return function increment() {
    count++
    return count
  }
}

const counter = createCounter()
console.log(counter()) // 1
console.log(counter()) // 2
// `count` недоступна снаружи напрямую — это приватное состояние

// Классическая ловушка с var:
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0) // 3, 3, 3
}
for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log(j), 0) // 0, 1, 2
}

Дополнительные вопросы

  • Почему let в цикле "чинит" проблему с замыканиями, а var — нет?
  • Могут ли замыкания привести к утечкам памяти?
  • Как реализовать приватные поля через замыкание вместо #privateField?