Замыкания. Почему в этом случае удаляется lexical environment родительской функции?
Цитата с learn.javascript.ru
В следующем коде, после того как g станет недоступным, лексическое окружение функции (и, соответственно, value) будет удалено из памяти:
function f() {
let value = 123;
function g() {
alert(value);
}
return g;
}
let g = f(); // пока g существует, соответствующее лексическое окружение существует
g = null; // ...а теперь память очищается
Я не понимаю почему лексическое окружение родительской функции будет удалено из памяти. Ведь мы по сути только очистили переменную g и сказали, что там ничего нет - g = null. Сама же вложенная функция осталась, ее никто не удалял.
Разве вложенная функция не будет всегда хранить ссылку на родительскую ф-цию (даже без вызова) просто потому что код вложенной функции есть внутри? Типа браузер видит ф-цию, потом видит внутри этой функции еще одну вложенную ф-цию и думает: "Ага, так как внутри функции есть еще одна - вложенная функция (пусть даже без вызова), лексическое окружение родительской функции удаляться уже не будет."
Как это происходит? Почему переприсвоение переменной, в которой лежит вложенная функция, удаляет лексическое окружение родительской функции f?
Ответы (1 шт):
По факту это работает так, что контекст функции f каждый раз пересоздается заново при каждом запуске функции. Поэтому у вас внутри функции f нет никакой хранящейся постоянной функции g, она будет создана каждый раз заново во время запуска.
function f() {
function g() {}
return g;
}
// false - это разные функции g, а не одна и та же
console.log(f() == f());
Пока вы храните ссылку на g она будет существовать, а она хранит ссылку на value в свою очередь и тоже будет существовать. Но как только вы потеряете эти ссылки, то обратиться к g уже никогда не сможете, ведь вызов f вернет совершенно новую функцию. Ну а мертвые ссылки подлежат удалению и они вам больше не к чему.