Автор Closures очень хорошо объяснил замыкания, объясняя причину, по которой они нам нужны, а также объясняет LexicalEnvironment, который необходим для понимания замыканий. Вот сводка:
Что делать, если к переменной обращаются, но она не является локальной? Как здесь:
В этом случае интерпретатор находит переменную во внешнем LexicalEnvironment
объекте.
Процесс состоит из двух шагов:
Когда функция создается, он получает скрытое свойство с именем [[Scope]], которое ссылается на текущую LexicalEnvironment.
Если переменная читается, но не может быть
Вложенные функции
Функции могут быть вложены друг в друга, образуя цепочку Лексических сред, которые также можно назвать цепочкой областей видимости.
Таким образом, функция g имеет доступ к g, a и f.
Замыкания
Вложенная функция может продолжаться
Разметка LexicalEnvironments:
g32]
Как мы видим, this.say
является свойством в объекте пользователя, поэтому он продолжает жить после завершения пользователем.
И если вы помните, когда this.say
создан, он ( как каждая функция) получает внутреннюю ссылку this.say.[[Scope]]
на текущий LexicalEnvironment. Итак, LexicalEnvironment текущего исполнения пользователя остается в памяти. Все переменные пользователя также являются его свойствами, поэтому они также тщательно хранятся, а не как обычно.
Все дело в том, чтобы убедиться, что если внутренняя функция хочет получить доступ к внешней переменной в будущем, .
Подводя итог:
Это называется замыканием.