TGViewer
Metaprogramming Metaprogramming @metaprogramming · 877 subscribers
Post #9 314
О замыканиях в JavaScript.

В JavaScript, на самом деле, не "настоящие" замыкания. Я бы даже сказал, что в JS нет замыканий, а есть некая отдалённо напоминающая их эмуляция.

Суть замыканий (closures) в двух вещах:
- в теле функции можно использовать переменные, которые определены до этой функции
- значения этих переменных "фиксируются" ("запираются") в момент определения функции

Посмотрим пример на Elixir-е — "настоящем" функциональном языке:

x = 2
plus_2 = fn(n) -> n + x end

plus_2.(10) # => 12

x = 3

plus_2.(10) # => 12

Итак, мы внутри функции plus_2 используем переменную x, которая определена до этой функции.

Прикол в том, что в момент определения функции значение этой переменной "фиксируется": внутри функции теперь это уже не какой-то там x, а конкретно оказавшаяся там двойка. На место свободной переменной x, фактически, подставляется конкретное содержащееся там в момент определения значение.

Поэтому в последней строке plus_2 всё также продолжает прибавлять двойку к своему единственному аргументу n, а не новое значение x. Исходное значение x "замкнулось" внутри функции.

В императивных языках, которые эмулируют эту функциональность (простите за тавтологию) функциональных языков, всё не так:

// js
let x = 2
plus_2 = n => n + x

plus_2(10) // 12

x = 3
plus_2(10) // 13

# ruby
x = 2
plus_2 = ->(n) { n + x }

plus_2.(10) # 12

x = 3
plus_2.(10) # 13

Как видим, в JS (и Ruby) функция не "запомнила" (не подставила) значение переменной внутри её тела. Вместо этого, она каждый раз заново обращается к этой переменной, используя текущее значение.

Конечно, одно из типовых использований замыканий — в "фабрике функций" (функциях, которые возвращают другие функции). И когда вы пишете код "внешней" функции (= самой фабрики), ничто не мешает тщательно контролировать самого себя на предмет того, какие переменные "утекают" во "внутреннюю" функцию (= результат работы фабрики, который будет возвращён коду, вызвавшему фабрику). И убедиться, что эти переменные никто не будет изменять вне внутренней функции, или их изменение учтено by design — например, с "неправильными" JS-замыканиями можно тривиально реализовать функцию, которая считает, сколько раз она была вызвана — а с "правильными" замыканиями это, фактически, невозможно:

// js

timesRunFactory = () => {
let count = 0;

return () => {
count++;
return count
}
}

timesRun = timesRunFactory();

timesRun(); // 1
timesRun(); // 2
...

#programming #fp
  • ❤ 1
More from @metaprogramming
  1. Sep 15, 2026Творческое мнение читателей по поднятым вопросам
  2. Sep 13, 2026Философский нейроколобок Феномен психологической проекции (читаешь и чувствуешь – он же жи…
  3. Sep 13, 2026Современные модели специально обучены отвечать нейтрально на вопрос о наличии у них сознан…
  4. Sep 12, 2026Нереализованный пафос математики в эпоху ИИ В связи с изложенным политическое возмущение м…
  5. Sep 12, 2026Математика как майнинг благодати? При чтении всего этого складывается впечатление, что мат…
  6. Sep 12, 2026Снова про борьбу математиков с ИИ Ещё два громких обсуждения в жанре "математики против ИИ…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →