So, I've been reading some things about closures, scopes, the lexical environment and the execution context. From my understanding the current execution context has a lexical environment and a variable environment (which seems to be a specific type of lexical environment from reading other threads on stack overflow and which I find mentioned in ECMAScript 2016 but not defined). The variable environment has the identifiers that were declared with var and the values associated with them. The lexical environment has, somewhere in its record, the bindings and the values of the variables declared with let and const. I have some questions related to this, however.
Is the variable environment just a variable environment record in the lexical environment (and for some reason the record part has fallen out) or is it a separate lexical environment that has an outer lexical environment reference to something(the outer variable environment or the outer lexical environment)?
Also, where do closures and scopes fit in this picture? From what I understand scope is just what is accessible by the current execution context but is it just the idea of what is accessible or does the definition of scope also include the way JavaScript searches for a variable, looking into the current lexical environment and variable environment and the subsequent environments on the scope chain? About closures, MDN defines a closure as "the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment)" and I see it used several times in ECMAScript 2016 - are closures just the beginning of the new execution context since they determine the lexical environment (what about the variable environment) and they "contain" the function?
Finally, where are variables with let and const stored in the current execution context? I saw in a few Stack Overflow threads that they are in the lexical environment (from searching in Google I couldn't find anything) - specifically, the first answer here (Where are global let variables stored?) says that "Because you used let rather than var, it gets stored in the declarative environment record associated with the global lexical environment object, rather than on the global object itself." and I assume it's the same in general. What about this situation:
function foo() {
let a = 1;
{
let a = 2;
console.log(a)
}
console.log(a)
}
foo()
What happens here - the two variables named "a" cannot be in the same lexical environment, right? So there are two lexical environments, but how is the second one created. Is a new execution context created at the beginning of the new block? Does that happen for every block or only ones that have new variables declared with let and const?
Sorry for all the questions, but my main one is the last one and I do not understand the basis for understanding it, which is why I asked all the questions. Thank you for your time.