按照 ECMAScript 规范理解 JavaScript super() 调用
Understanding JavaScript super() invocations by following the ECMAScript specification
代码
class Parent {
constructor() {}
}
class Child extends Parent {
constructor() {
super();
}
}
背景
当我试图准确理解 class 构造函数中的 super()
调用是如何工作时,我遵循了以下 ECMAScript 操作顺序:
- new Child() calls ChildConstructor.[[Construct]]
kind
是 derived(早先在 14.5.15 中设置),因此没有绑定新的 this
值
- OrdinaryCallEvaluateBody 被调用,最终评估
Child
class 构造方法的主体,其中 super()
是第一条语句
- super() calls ParentConstructor.[[Construct]],这会将我们带回 步骤 3,这次只是将
kind
作为 base
- 由于
kind
现在是 base,一个新的 this
绑定被创建并绑定到 Environment Record 为 Parent
构造函数 创建的新 函数环境
-
Parent
构造函数主体的其余部分执行,一旦完成控制流回 Child.[[Construct]]
从第 11 步继续执行
- 最后,
Child.[[Construct]]
尝试 return envRec.GetThisBinding
问题
在 Child.[[Construct]]
的 step 6
中创建的 Child
构造函数的 Environment Record 没有 this
绑定( [[ThisBindingStatus]]
是 未初始化的 )。因此,当我们尝试在步骤 8 中执行 envRec.GetThisBinding
时,据我所知,我们应该得到一个 ReferenceError
(as specified here).
我在这里错过了什么?我似乎不明白为什么 Child
构造函数不会抛出错误,事实上如果 Child
构造函数的 [[ThisValue]]
被设置了。
您错过了 super()
link 中的一个步骤:
- Let
newTarget
be GetNewTarget()
.
- Assert:
Type(newTarget)
is Object.
- Let
func
be ? GetSuperConstructor()
.
- Let
argList
be ArgumentListEvaluation
of Arguments
.
ReturnIfAbrupt(argList)
.
- Let
result
be ? Construct(func, argList, newTarget)
.
- Let
thisER
be GetThisEnvironment( )
.
- Return ?
thisER.BindThisValue(result)
.
步骤 6
如您所述调用 ParentConstructor.[[Construct]]
,但随后第 8 步会将 Child
构造函数主体中的 this
绑定设置为构造值,因此当envRec.GetThisBinding
在 ChildConstructor.[[Construct]]
结束时运行,this
绑定将在那里
代码
class Parent {
constructor() {}
}
class Child extends Parent {
constructor() {
super();
}
}
背景
当我试图准确理解 class 构造函数中的 super()
调用是如何工作时,我遵循了以下 ECMAScript 操作顺序:
- new Child() calls ChildConstructor.[[Construct]]
kind
是 derived(早先在 14.5.15 中设置),因此没有绑定新的this
值- OrdinaryCallEvaluateBody 被调用,最终评估
Child
class 构造方法的主体,其中super()
是第一条语句 - super() calls ParentConstructor.[[Construct]],这会将我们带回 步骤 3,这次只是将
kind
作为 base - 由于
kind
现在是 base,一个新的this
绑定被创建并绑定到 Environment Record 为Parent
构造函数 创建的新 函数环境
-
Parent
构造函数主体的其余部分执行,一旦完成控制流回Child.[[Construct]]
从第 11 步继续执行 - 最后,
Child.[[Construct]]
尝试 returnenvRec.GetThisBinding
问题
在 Child.[[Construct]]
的 step 6
中创建的 Child
构造函数的 Environment Record 没有 this
绑定( [[ThisBindingStatus]]
是 未初始化的 )。因此,当我们尝试在步骤 8 中执行 envRec.GetThisBinding
时,据我所知,我们应该得到一个 ReferenceError
(as specified here).
我在这里错过了什么?我似乎不明白为什么 Child
构造函数不会抛出错误,事实上如果 Child
构造函数的 [[ThisValue]]
被设置了。
您错过了 super()
link 中的一个步骤:
- Let
newTarget
beGetNewTarget()
.- Assert:
Type(newTarget)
is Object.- Let
func
be ?GetSuperConstructor()
.- Let
argList
beArgumentListEvaluation
ofArguments
.ReturnIfAbrupt(argList)
.- Let
result
be ?Construct(func, argList, newTarget)
.- Let
thisER
beGetThisEnvironment( )
.- Return ?
thisER.BindThisValue(result)
.
步骤 6
如您所述调用 ParentConstructor.[[Construct]]
,但随后第 8 步会将 Child
构造函数主体中的 this
绑定设置为构造值,因此当envRec.GetThisBinding
在 ChildConstructor.[[Construct]]
结束时运行,this
绑定将在那里