The ECMAScript 5 spec states the following:
Usually a Lexical Environment is associated with some specific
syntactic structure of ECMAScript code such as a FunctionDeclaration,
a WithStatement, or a Catch clause of a TryStatement and a new Lexical
Environment is created each time such code is evaluated.
If my understanding is correct, then when a new Lexical Environment is created in JavaScript, a new scope is entered, which is why variables declared inside a function are not visible outside of that function:
function example() {
var x = 10;
console.log(x); //10
}
console.log(x); //ReferenceError
So in the above function declaration, a new Lexical Environment is created, which means x is not available in any outer Lexical Environments that may exist.
So the part of the quote above about Function Declarations seems to make sense. However, it also states that a new Lexical Environment is created for the Catch clause of a Try Statement:
try {
console.log(y); //ReferenceError so we enter catch
}
catch(e) {
var x = 10;
console.log(x); //10
}
console.log(x); //10 - but why is x in scope?
So how does the scope of a catch block work? Do I have a fundamental misunderstanding of what a Lexical Environment is?
If I understand it right, then what it probably means is that, in your code,
ewill only exist in the catch block. Tryconsole.log(e);outside the catch block and it will throw ReferenceError.As with WithStatement,
with ({x: 1, y: 2}) { }, x and y will only exist inside the with block.But it doesn’t mean that
vardeclarations will be bound to the closest lexical environment. Actually,vardeclarations will be bound to the environment when entering an execution context.10.5 Declaration Binding Instantiation: when the execution context in being entered, it will look for function declarations, arguments, and variable declarations and then create bindings in the execution context’s VariableEnvironment.
So any variables that are declared using
varwill be accessible anywhere in the function regardless of the control structures or where it is defined inside the function. Note that this does not include nested functions as they’re a separate execution context.That means the
vardeclarations will be bound to the closest execution context.So in above code,
x = 5;will set thexvariable inside the inner function, becausevar x;insideif (false) { var x; }is bound to that function already before the function code is executed.