function foo(bar) {
this.name = bar;
}
During the compilation phase, when the JavaScript Engine is compiling the function foo
, I understand that it registers bar
in the scope of foo
, but how is this.name
parsed ? Given that the execution context that this
points to is determined by the call-site of the function, does this mean that this
is not parsed at all until run-time ? I know that value assignment occurs during run-time and we're assigning a value (name
) on an object(this
), so I'm assuming the line this.name = bar
is not parsed at all from the perspective of scope resolution. Is this correct ?
CodePudding user response:
"Parsing", "scope resolution", "compilation" (optimization, jit, or whatever, if at all), "run-time", can all be conceptualized as separate phases (which might be intertwined in the actual implementation).
In an actual implementation, the this
-keyword-token is most likely parsed just like any other reserved keyword token during the parsing phase, nothing special about that.
The scope of the this
-keyword can be determined statically, just like the scope of variables like bar
. Consider this more interesting example to understand what it means:
var f = function(x) {
var g = (y) => {
this.name = x * y;
}
return g
}
In this example, we would know statically during the scope-analysis phase that:
this
is the receiver off
(which will be bound dynamically at the invocation site off
, i.e. we can know statically that it belongs tof
, but we don't know until runtime what the receiver might be)x
is a parameter off
y
is a parameter ofg
name
is just a statically known constant stringy-valued property name; It has no "scope" at all, you can think of it as a hard-coded constantthis['name'] = ...
.
The value that is used during the evaluation of this
is bound at the call site at runtime, it's either the receiver if the function is called as a method, or a suitable global object / module if f
is called as stand-alone function without a receiver.
Note that the specification does not force the interpreter to analyze anything statically: this is an implementation detail that is left to the one who implements the interpreter. A really sophisticated interpreter might decide to perform some escape analysis, and when it finds that, for example, some nested helper functions don't escape the scope of the enclosing function, it might try to compute the receivers ahead of time, or to inline the entire helper function at the call site.
CodePudding user response:
It's parsed at parse time, which you might also call compile time, but the distinction is tricky in modern optimised JITs. Either way, scope resolution is static, and the scopes involved in the expression this.name
are resolved at the same time as the scope of bar
.
The scope of the this
keyword is the function
(just like for the bar
variable in your example), you can think of it as constant variable in the function scope, initialised from an invisible zeroth argument.
.name
is not resolved at all since it's not a variable, it's a property name. The location in the target object will depend on the particular object; the property is looked up right when the assignment happens, when the function is called.
CodePudding user response:
You've mentioned three different stages of code processing: parsing, compilation, and runtime.
During the compilation phase
Indeed, some interpreters may introduce compilation for optimization reasons, but this kind of compilation is not the same thing as compilation in Java or other compiled languages; e.g., you don't get to see compilation errors (an example of such error would be number is not assignable to a string
). For this reason, JavaScript is thought of as an interpreted language, not compiled one.
does this mean that
this
is not parsed at all until run-time ?
It is parsed, but not compiled. The expression this.name = bar
is parsed as
<left-hand-operand> <binary-operation> <right-hand-operand>
… and evaluated at runtime as (roughly) "take the value of bar
and put it to this.name
". If this cannot be done for some reason (e.g., if this
is nullish), there will be a runtime error.