【问题标题】:Understanding JavaScript super() invocations by following the ECMAScript specification按照 ECMAScript 规范理解 JavaScript super() 调用
【发布时间】:2019-01-22 13:09:52
【问题描述】:

代码

class Parent {
  constructor() {}
}

class Child extends Parent {
  constructor() {
    super();
  }
}

背景

当我试图准确了解类构造函数中的super() 调用如何工作时,我遵循了以下ECMAScript 操作序列:

  1. new Child() 致电ChildConstructor.[[Construct]]
  2. kind派生的(之前在14.5.15 中设置),因此没有绑定新的this
  3. 调用OrdinaryCallEvaluateBody,最终评估Child类构造方法的主体,其中super()是第一条语句
  4. super() 调用 ParentConstructor.[[Construct]],这会将我们带回到第 3 步,这次只是将 kind 作为 base
  5. 由于kind 现在是base,因此会创建一个新的this 绑定并将其绑定到新函数环境的Environment Record > 为Parent 构造函数创建
  6. Parent 构造函数主体的其余部分执行,一旦完成,控制流回到Child.[[Construct]],从第 11 步继续执行
  7. 最后,Child.[[Construct]] 尝试返回envRec.GetThisBinding

问题

Child.[[Construct]]step 6 中创建的Child 构造函数的环境记录没有this 绑定([[ThisBindingStatus]]未初始化的) .因此,当我们尝试在第 8 步中执行 envRec.GetThisBinding 时,据我所知,我们应该得到一个 ReferenceError (as specified here)。

我在这里缺少什么?我似乎不明白为什么 Child 构造函数不会抛出错误,而且确实是否设置了 Child 构造函数的 [[ThisValue]]

【问题讨论】:

  • 我试图在规范中找到这些行,但我的所有搜索都失败了。那些文字引用还是你在解释?您能否链接到您要询问的特定部分?
  • 感谢您的关注,@Barmar。上面的步骤是实际发生的事情的一个非常浓缩的版本。步骤太多,无法一一罗列,但为了方便参考,我在关键步骤处链接了重要的算法。

标签: javascript class ecmascript-6 ecmascript-2017


【解决方案1】:

您在super() 链接中错过了一步:

  1. newTarget 成为GetNewTarget()
  2. 断言:Type(newTarget) 是对象。
  3. func 成为? GetSuperConstructor()
  4. argList 成为ArgumentListEvaluationArguments
  5. ReturnIfAbrupt(argList)
  6. result 成为? Construct(func, argList, newTarget)
  7. thisER 成为GetThisEnvironment( )
  8. 返回 ? thisER.BindThisValue(result)

步骤6 调用ParentConstructor.[[Construct]] 如您所述,但是步骤8 会将Child 构造函数主体中的this 绑定设置为构造值,因此当envRec.GetThisBinding 在结束时运行@987654342 @,this 绑定将在那里

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多