I'm reading about JavaScript closures. I'm familiar with Execution Contexts, how the Lexical Environment is maintained, and very familiar with Lexical Scoping.
I want to know how closures in JavaScript are created and maintained. Sometimes it's hard for me to grasp such important concepts without knowing how it is actually doing it. I know that, according to Wikipedia, a closure is
is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables (also called free variables) of that function.
But my question is, I want to know how, according to the ECMA Specification, that a closure is created and maintained. I'm not looking for a high-level explanation of closure theory, please reference the ECMA Specification in your answer.
Note: Please do not consider this a duplicate, unless the answer explains a closure using the ECMA Specification. Again, I'm not interested in someone quoting wikipedia and giving an example, I want to fully understand how JavaScript does this. (I'm familiar with this question on SO).
According to the Wikipedia definition, as mentioned in the question, a closure is a
The understanding of how execution contexts and lexical environments are maintained is known and the goal here is to understand when a function is returned, how is that referencing environment maintained/referenced?
Let's begin.
In section 8.6.2 on the ECMA 262 v 5 specification, it lists the internal properties of ECMAScript objects. The one to point out here is in table 9, the [[Scope]] property. According to the description of this property, it is described as
As we will see, the [[Scope]] property of a function object will always be set to the parent's lexical environment. We see this mentioned in section 13.2 which talks about the process of creating a function object. (Please note: function object in this context is referring to a native ECMAScript object, and not the accessible function object through code).
When a function is created, it sets the internal [[Scope]] property to the VariableEnvironment, LexicalEnvironment or Global Environment of the running execution context, depending on if the function is a function declaration, function expression or created through the Function constructor.
When control is given over to the global code, as well as when control enters function code, declaration binding instantiation occurs as part of initializing the execution context. Part of the declaration binding instantiation is to bind the function declarations within the scope of the current context by creating the function objects as mentioned in section 13.2. The below example shows this:
For example
Another thing to look is the process that occurs upon entering/creating the execution context when entering a function. Below is a summary of what happens.
With the knowledge that a function maintains a reference to it's parent Lexical Environment through the internal [[Scope]] property, we can now see how closures work.
So to answer the question, a functions parent LexicalEnvironment is persisted through the internal [[Scope]] property of the function. Note that local variables within the function can be resolved when the function is run, only "free variables" need to be tracked and are done so by the [[Scope]] property.
Note: Please, if my information is incorrect, comment below.