JavaScript报错TypeError: Receiver must be an instance of class Child原因咨询
问题分析与解答
错误原因
这不是JavaScript引擎的Bug,而是ECMAScript规范对私有方法的约束导致的,核心在于私有方法的静态绑定特性和类构造函数的执行顺序:
- 执行
new Child()时,先进入Child构造函数,立即调用super()(即Base的构造函数) - 在
Base构造函数中调用this._public(),此时this确实指向Child实例,但Child构造函数还未完成super()之后的初始化流程——从规范层面,这个实例还没被完全标记为Child类的实例 - 进入
Child的_public方法后,尝试调用this.#privateMethod():私有方法是静态绑定到定义它的类(Child)的,只有当实例被完全确认为Child类的实例时,才能访问该类的私有成员。而super()执行阶段实例未完成子类初始化,因此引擎判定无法访问该私有方法,抛出错误。
Firefox的错误信息翻译为:
未捕获的类型错误:无法访问私有字段或方法:对象不是正确的类
修复方案
调整_public方法的调用时机,让它在子类构造函数的super()执行完成后再调用,示例代码如下:
'use strict'; class Base { constructor() { // 移除父类构造函数中的this._public()调用 } } class Child extends Base { constructor() { super(); // 在super()之后调用,此时实例已完成子类初始化 this._public(); } _public() { this.#privateMethod(); } #privateMethod() { this.bar = 1234; } } const c = new Child(); console.log(c.bar); // 输出1234
如果父类必须在构造函数中触发该方法,可以将私有方法改为约定式的受保护方法(比如命名为_privateMethod),但这会失去真正的私有性,需根据实际需求选择。
内容的提问来源于stack exchange,提问作者d.k
相关产品推荐
相关产品推荐

