Refer to the specification :
Catch : catch ( CatchParameter ) Block
- oldEnv is saved LexicalEnvironment from the current context
- create catchEnv as a NewDeclarativeEnvironment (oldEnv) .
- MutableBinding is created for each argument name from BoundNames to CatchParameter in catchEnv
- The current LexicalEnvironment in the context is set to catchEnv.
- BindingInitialization result is saved in status .
- if status is not normal
- the current LexicalEnvironment in the context is set to oldEnv
- the catch value of the block is set to status
- B stores the result of the execution of a Block.
- the current LexicalEnvironment in the context is set to oldEnv
- the catch value of the block is set to B
What can be noted in this algorithm?
- when you enter catch , a new LexicalEnvironment is created
- the values specified in the catch parameters are associated with the new LexicalEnvironment
- on exit, the old LexicalEnvironment is always restored
Thus e
declared above var e=10
overlaps e
in the expression catch (e)
, the value of which is used inside the block.
And since the old LexicalEnvironment is restored when exiting the block, the variable declared through var will be visible inside the finally block.
Now you can go to the question from the comment:
@VladimirGamalian, but doesn’t NewDeclarativeEnvironment mean your own scop? But catch doesn't have it? Or is it such magic due to the ascent of ads that all pops up except for the exception? Somehow strange it turns out ...
In the execution context, there are two additional properties.
- LexicalEnvironment - defines the Lexical Environment , which stores the identifiers created in the code in the current context
- VariableEnvironment - defines the Lexical Environment in which the EnvironmentRecord stores the bindings created with VariableStatements in the current context
When using the var
expression, variables are added to the VariableEnvironment of the current context. Since when entering a catch
only LexicalEnvironment changes - it becomes irrelevant where the variable is declared with var
- it will still be added to the VariableEnvironment and will be accessible from anywhere in the current execution context.