咨询MDN中JavaScript类求值顺序的两处疑惑
关于JavaScript类求值顺序的两个问题解答
问题1:class bar extends null {}报错的原因
MDN描述的是类定义阶段的规则:extends子句的求值结果只要是有效构造函数或null,就不会在这个阶段抛出错误。class bar extends null {}本身的定义符合该规则,不会在定义时报错。
你遇到的TypeError: Super constructor null of bar is not a constructor属于实例化阶段的错误:当尝试new bar()时,派生类的默认构造函数会自动调用super(),而super()需要调用父类构造函数创建实例,但null不是可调用的构造函数,因此触发报错。两者分属不同阶段,并不矛盾。
问题2:实例字段初始化顺序的实际结果与MDN描述差异的原因
先明确实际执行顺序(给代码添加日志可验证):
- 进入
P的构造函数,执行super()调用 - 进入
F的构造流程:- 先执行
F的实例字段初始化:this.x = 1 - 再执行
F构造函数内的代码:this.y = 10
- 先执行
super()执行完成,回到P的构造函数:- 先执行
P的实例字段初始化:this.j = 2 - 再执行
P构造函数内super()之后的代码:this.k = 20
- 先执行
你标注的顺序(super()→x=1→y=10→j=2→k=20)存在错误,实际x=1是在F构造函数代码执行前完成的,j=2是在super()执行完成后才进行的。
MDN描述中“基类在构造函数开始时”是准确的——基类实例字段初始化确实在构造函数体代码执行之前;但“派生类在super()调用返回前立即执行”的表述有歧义,准确规则是:派生类的实例字段初始化在super()调用完成之后、派生类构造函数剩余代码执行之前。差异源于对MDN表述的误解,或是MDN表述不够精准导致的。
内容的提问来源于stack exchange,提问作者desen zhao
相关产品推荐
相关产品推荐

