Не до конца понимаю как работают замыкания JS

Есть стандартный код

function counter(){
    let a=0;
    return function (){
        a++;
        console.log(a);
    }
}
 
count = counter();
count()
count()
count()

Если честно не понимаю почему а сохраняет предыдущее значение и таким образом увеличивается каждый раз на 1, а не сбрасывается в 0 при каждом вызове.

Недопонимание начинается здесь

count = counter(); 

Здесь сначала выполняется ф-я counter, в ней была объявлена переменная a=0, а возвращаемая анонимная функция попала в переменную count После того как функция counter выполнилась (в этом месте count = counter() ), она не вылетает из памяти? Ну т.е. после ее запуска, анонимная функция, которую я вызываю через count() теперь постоянно будет видеть переменную "a" внутри counter и при каждом новом вызове соответственно увеличивает предыдущее значение переменной "a" на 1? Так что ли?

Или же анонимная функция не дает выбросить из памяти переменную "a" в функции counter, поскольку это является ее внешним окружением?

Если сформулировать вопрос проще, то я не могу понять, что происходит с кодом функции после ее вызова. Вызвал функцию она выполнилась и вылетела из памяти или вызвал функцию и теперь ее код с этого момента всегда доступен?


Ответы (3 шт):

Автор решения: Voprositel

В переменную count помещается не только возвращаемое значение, но и объявленные в теле функции переменные. Переменная не удаляется после выполнения функции.

→ Ссылка
Автор решения: Дмитрий Гаврилов

Помогла статья фывфывhttps://learn.javascript.ru/closure введите сюда описание изображения

→ Ссылка
Автор решения: Aziz Umarov

А если посмотреть на это в контексте OOП, то примерно это будет так

function counter(){ // класс counter 
    let a=0; // поле a в классе counter, инициализированное 0
    return function (){ // метод по умолчанию
        a++;
        console.log(a);
    }
   // собственно методов может быть очень много и один по умолчанию
}
 
count = counter(); // вызов конструктора counter который вернет объект созданный в куче.
count(); // вызов default метода объекта count

и сразу жить проще как-то. И то что это объект и создается он в куче и сборщик его почистит когда придет время

→ Ссылка