繁体   English   中英

JS引擎在编译阶段如何解析'this'关键字?

[英]How is the 'this' keyword parsed by the JS engine during the compilation phase?

function foo(bar) {
  this.name = bar;
}

在编译阶段,当 JavaScript 引擎编译 function foo时,我知道它在this.namefoo中注册了bar ,但是如何解析这个名称? 鉴于this指向的执行上下文由 function 的调用站点确定, this是否意味着直到运行时才对其进行解析? 我知道值分配发生在运行时,我们在对象( this )上分配一个值( name ),所以我假设this.name = bar从 scope 分辨率的角度来看根本没有解析. 这个对吗?

它在解析时进行解析,您也可以将其称为编译时,但在现代优化的 JIT 中区分是棘手的。 无论哪种方式,scope 的分辨率都是 static,表达式this.name所涉及的范围与bar的 scope 同时解析。

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根本没有解析,因为它不是变量,而是属性名称。 目标 object 中的位置将取决于特定的 object; 当分配发生时,当调用 function 时,会立即查找该属性。

您已经提到了代码处理的三个不同阶段:解析、编译和运行时。

在编译阶段

确实,有些解释器可能会出于优化的原因引入编译,但这种编译与 Java 或其他编译语言中的编译不是一回事; 例如,您不会看到编译错误(此类错误的一个示例是number is not assignable to a string )。 出于这个原因,JavaScript 被认为是一种解释语言,而不是编译语言。

this是否意味着直到运行时才完全解析它?

它被解析,但没有被编译。 表达式this.name = bar被解析为

<left-hand-operand> <binary-operation> <right-hand-operand>

...并在运行时评估为(大致)“获取bar的值并将其放入this.name ”。 如果由于某种原因不能这样做(例如,如果this是无效的),则会出现运行时错误。

“解析”、“范围解析”、“编译”(优化、jit 或其他任何东西,如果有的话)、“运行时”,都可以概念化为单独的阶段(可能在实际实现中交织在一起)。

this -keyword-token 在解析阶段就像任何其他保留的关键字令牌一样被解析,没什么特别的。

this -keyword 的 scope 可以静态确定,就像bar等变量的 scope 一样。 考虑这个更有趣的例子来理解它的含义:

var f = function(x) {
  var g = (y) => {
    this.name += x * y;
  }
  return g
}

在此示例中,我们将在范围分析阶段静态地知道:

  • thisf的接收者(它将在f的调用站点动态绑定,即我们可以静态知道它属于f ,但直到运行时我们才知道接收者可能是什么)
  • xf的参数
  • yg的参数
  • name只是一个静态已知的常量字符串值属性名称; 它根本没有“范围”,您可以将其视为硬编码常量this['name'] =...

在评估this中使用的值在运行时绑定在调用站点,如果将 function 作为方法调用,则它是接收器,或者如果f作为独立调用 ZC1C424Z074E67A94F1接收者。

请注意,规范并不强制解释器静态分析任何内容:这是一个实现细节,留给实现解释器的人。 一个非常复杂的解释器可能会决定执行一些转义分析,例如,当它发现一些嵌套的帮助函数没有转义封闭 function 的 scope 时,它可能会尝试提前计算接收器,或者内联呼叫现场的整个助手 function。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM