The following code always prints the argument passed in to parameter a
, regardless of the presence of a variable with the same name.
Presumably because parameter identifiers are bound separately to variables in scope. Where are they positioned? Are they in the lexical environment?
function foo(a, b = () => a) {
var a = 1
console.log(b())
}
foo() // undefined
foo(2) // 2
Is it that var
declarations end up in the special VariableEnvironment, while parameters are positioned in the LexicalEnvironment? And let
and const
avoid conflict by making redefinition an early error?
Relevant also:
A lexical environment is a data structure that holds identifier-variable mapping. (here identifier refers to the name of variables/functions, and the variable is the reference to actual object [including function type object] or primitive value).
JS: Lexical Environment. The scope is where a variable is available in your code. Each block of code creates scope and a lexical environment. The outermost context where a variable is the lexical environment of that variable irrespective of order or sequence.
While the lexical environment refers to this global environment, the variable environment only refers to variables created within the scope of the provided function within the lexical environment. The variable environment maps the local scope of a given environment.
Lexical Environment is the environment of the function where it is written. That is, the static order/place where it is situated, regardless from where it is called from. Scope of a variable/function is basically the locations from where a variable is visible/accessible.
In the event that any default values are present, a separate environment record is created for parameters.
The semantics of functions declared in this position are such that this environment record defines their local scope. A note in the spec (see clause 28) says:
NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body.
More from the spec:
When an execution context is established for evaluating an ECMAScript function a new function Environment Record is created and bindings for each formal parameter are instantiated in that Environment Record. Each declaration in the function body is also instantiated. If the function's formal parameters do not include any default value initializers then the body declarations are instantiated in the same Environment Record as the parameters. If default value parameter initializers exist, a second Environment Record is created for the body declarations. Formal parameters and functions are initialized as part of FunctionDeclarationInstantiation. All other bindings are initialized during evaluation of the function body.
In the absence of default arguments, therefore, I deduce that one of the pre-existing lexical environments (VariableEnvironment or LexicalEnvironment) is used for parameter bindings. Maybe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With