Size: a a a

2019 December 01

T

Theo in JS
А makeCounter()() каждый раз видит count=0
источник

W

WwW in JS
Vermin
Функция запоминает скоуп
функция counter1 запомниает скоуп, да?
источник

W

WwW in JS
Theo
А makeCounter()() каждый раз видит count=0
вот в этом вопрос. counter1 запоминает, а makeCounter нет.
источник

T

Theo in JS
Ну да
источник

W

WwW in JS
а почему?)))
источник

T

Theo in JS
Вроде уже объяснили выше
источник

T

Theo in JS
Vermin
@What_a_W0nderfu1_W0r1d у функций есть:
а) собственное лексическое окружение, в котором записаны переменные.
б) скрытое свойство scope, в котором содержится ссылка на внешнее лексическое окружение.

let counter1 = makeCounter() передает в переменную counter1 анонимную функцию с инкрементированием переменной count.
Анонимная функция имеет свойство scope, которое содержит ссылку на лексическое окружение, в котором та была создана (т .е. на makeCounter) и запоминает его.
Потом, ты вызываешь АНОНИМНУЮ ФУНКЦИЮ (!!!) с помощью переменной count1 -- count1(), вот так. Функция ищет в своем лексическом окружении переменную count, не находит и обращается через scope к лексическому окружению на уровень выше, т.е. к самой makeCounter, в котором ее находит.
Scope makeCounter'а, кстати, ссылается на window, и, если не находит переменную в своем окружении, может взять ее снаружи, прямо глобальную, да.
.
источник

V

V L A S O V in JS
WwW
а почему?)))
Потому что так работает замыкания
источник

V

Vermin in JS
WwW
функция counter1 запомниает скоуп, да?
Да.
let counter1 = makeCounter()
counter1()
Получает переменную из ссылки на лексическое окружение makeCounter своего scope, она изменяется при каждом вызове. Переменная как бы ЗАМЫКАЕТСЯ внутри функции makeCounter.

makeCounter()() имеет скоуп
makeCounter.[[Scope]] = window, но не обращается к нему, т.к. все нужные переменные находятся внутри. Замыкания не происходит, скоуп не меняется
источник

V

Vermin in JS
Поделай каты на коудворс на замыкания, без практики это проблематично осознать и принять
источник

В

Валик in JS
до вызова makeCounter функция объявленная в теле этой функции еще не инициализирована и не существует до вызова этой функции, в момент вызова  makeCounter инициализируются функция объявленная в ее теле и при  makeCounter()() ты сразу инициализируешь и вызываешь эту функцию, она отрабатывает и если ее результат нигде не используется, то она просто удаляется, нет никакого смысла ее держать в памяти, так работает garbage collection, при повторном вызове всё происходит сначала инициализация -> работа функции -> очищение памяти, если ты makeCounter() записываешь в переменную, то в этой переменно сохраняется функция, которая была инициализирована в теле makeCounter и сохраняется вмесе со всеми доступными ей переменными (скоуп) и теперь garbage collection ее не грохнет и мы можем вызывает ее много раз
источник

V

Vermin in JS
Справедливости ради, сборщик удаляет не функции, а их лексическое окружение
источник

V

Vermin in JS
Т.к. функция не является объектом, а окружение является
источник

W

WwW in JS
а т.е. я вызвал анонимную функцию. она отработал, а сборщик удалил. а если я её записал в переменную, то окружение сохраняется и в этом окружени как раз и записывается значение переменной. кажется я начал осознавать)))) ща надо понять, почему очищается окружение анонимной функции, а удаляется ещё и значение переменной
источник

W

WwW in JS
всем спасибо огромное. вы помогли довольно хорошо продвинуться. дальше я уже додумаю. надо просто всё уложить в голове. может порисую посижу схемы
источник

V

Vermin in JS
источник

W

WwW in JS
можно ли сказать, что всё дело в анонимной функции? её лексическое окружение существует только в момент её вызова и объявления собственно. поэтому нам и нужна переменная, которая будет хранить в себе лексическое окружение функции. так же работает и объявление функции(забыл как называется): let func = function() {}; по сути это запись анонимной функции в переменную. верно?
источник

W

WwW in JS
всё дело это я имею в виду необходимость присутствия переменной counter1
источник

T

Theo in JS
+
источник

T

Theo in JS
Не обязательно переменная, можно привязать к ключу какого-то объекта, например: obj.f = makeCounter()
источник