You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何从父类构造函数调用的方法无法设置子类私有字段?

子类私有字段在父类构造器调用的方法中无法访问的原因

代码示例

class Superclass {
  constructor() {
    this.setPrivateField();
  }

  setPrivateField() {
    // No implementation
  }
}

class Subclass extends Superclass {
  #field;
  setPrivateField() {
    console.log(this);
    this.#field = 1;
  }
}

new Subclass();

控制台输出

Subclass {}
test.js:16
    this.#field = 1;
                ^

TypeError: Cannot write private member #field to an object whose class did not declare it
    at Subclass.setPrivateField (test.js:16:17)
    at new Superclass (test.js:5:10)
    at new Subclass (test.js:12:1)
    at Object.<anonymous> (test.js:20:1)
    at Module._compile (node:internal/modules/cjs/loader:1434:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1518:10)
    at Module.load (node:internal/modules/cjs/loader:1249:32)
    at Module._load (node:internal/modules/cjs/loader:1065:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:158:12)
    at node:internal/main/run_main_module:30:49

Node.js v22.2.0

问题疑问

#field字段在Subclass中声明,且控制台已确认对象类型为Subclass,为何会触发该TypeError?原以为是V8引擎的bug,但Firefox浏览器中也存在相同表现。

原因解析

这不是引擎bug,而是JavaScript类继承的初始化顺序规则导致的:

  • 执行new Subclass()时,会先调用父类Superclass的构造器,此时子类自身的构造逻辑还未启动。
  • 父类构造器调用this.setPrivateField(),由于this指向Subclass实例,实际执行的是子类的同名方法。
  • 但子类的私有字段#field是在子类构造器执行阶段才会绑定到实例上,此时父类构造器仍在运行,子类的初始化步骤(包括私有字段的创建)尚未完成,实例上并没有#field这个私有成员。
  • 虽然console.log(this)显示实例类型是Subclass,但私有字段的存在与否不影响实例的类型标识,此时尝试给未初始化的私有字段赋值,就会触发TypeError。

简单总结:父类构造器先执行,子类私有字段还未被创建,调用子类方法赋值自然找不到对应的私有成员。

内容的提问来源于stack exchange,提问作者Natalie Weizenbaum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:18:20