Question:
I'm learning JS
at http://learn.javascript/ , currently reading the "Closing a function from the inside" subsection of the "Closures, scope" section.
The "Returning a Function" section describes an example with a nested function.
I actually don't understand how counter
remembers the currentCount
variable every time it is run, given what was written in the same section that the LexicalEnviroment
is erased from memory every time the function ends, and it is recreated every time it is started.
I don't understand where currentCount
is stored if the lexical environment is erased every time?
Answer:
Questions like these bring tears to my eyes.
It's simple – LexicalEnvironment
is indeed destroyed after the call ends.
But in the example, the work is not finished, because the returned function retained a reference to the parent [ makeCounter
] variable object.
That is, while the returned function is alive, the parent LE must be preserved, what if, when executing, you need to turn to the parent function for variables (which happens: there is no currentCount
variable in the returned function)?
Garbage collectors work according to the reference algorithm (Mark and sweep), in general it is something like this:
- Roots are found, that is, something that will always exist (in browsers, this is the
window
object, but it cannot be deleted). - After each awakening, he [the collector] recursively walks the roots and marks everything he can reach; it is considered necessary and useful. Everything else is considered unattainable and the memory from under them is returned to the environment.
Now remember that the returned function, conditionally stored in window
, refers to the parent LexicalEnvironment
via the [[Scope]]
hidden property.
The collector simply cannot remove it – window -> counter -> [[Scope]]
.
This explains why the new makeCounter
call created a pristine counter – each function call gives it a crystal new LexicalEnvironment
.
Closures are a very interesting thing in general, which can be very powerful, and can be completely confusing if you don't know how closures work.