consider the following code
var myVar = 'Hola';
{
let myVar;
myVar = 'Hello'
}
on line 4(myVar = 'Hello'
) we are using the Assignment operator
Now when i was looking at ecma262 in Assignment Operators Evaluation
it says that the left side in assignment operators is LeftHandSideExpression and the right side is AssignmentExpression
in other words it looks like that
LeftHandSideExpression = AssignmentExpression
can anyone explain to me how myVar is going to get evaluated ? if it's supposed to be LeftHandSideExpression ?
The main piece to understand is that evaluate
in this context means we're running these Runtime Semantics: Evaluation
sections for the various grammar pieces in the language. In the case of
myVar = 'Hello'
if we look at 13.15.2 Runtime Semantics: Evaluation for the evaluation of AssignmentExpression
the line
1.a. Let lref be the result of evaluating LeftHandSideExpression.
will drill down through the various steps until you eventually end up running 13.1.3 Runtime Semantics: Evaluation which defines the evaluation behavior of myVar
.
The key thing if you step through this is that lref
does not evaluation to a JS value, it evaluates to a Reference Record
type, which isn't a value JS code is aware of, but represents the concept of a location where a value can be assigned. In the case of your snippet, it's basically a reference to the scope where the variable list, and the name of the variable, so when assignment is performed later, it is fully resolves later.
This is behavior of evaluating the left side first more important for examples like this:
foo().bar = val();
because evaluating the left means that foo()
runs before val()
, which is what you'd expect. In this case foo()
runs and then we get a Reference Record
with the return value of foo()
as the target of the assignment, and bar
as the property name to assign.
Going back to 13.15.2 Runtime Semantics: Evaluation, we get to
1.e Perform ? PutValue(lref, rval).
which is where the final assignment happens. rval
is the "Hello"
string itself since it has been evaluated. If you take a look at 6.2.4.6 PutValue ( V, W ), you can probably guess that the 3rd section is what we end up with for a variable assignment
so in you're case it's
(<scope with closest `var/let myVar`).SetMutableBinding("myVar", "Hello", false)