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

JavaScript中同一类无法访问私有字段?TypedMap子类报错排查

错误原因分析

你遇到的报错核心有两个关键诱因:

1. 私有字段声明位置错误

JavaScript的私有字段(#前缀)必须在类的顶层作用域声明,不能放在构造函数内部。如果你的代码是在构造函数里写#keyType和#valueType,那这些只是构造函数的局部私有变量,不属于实例的私有字段。当重写的set方法试图访问this.#keyType时,因为类本身没有声明这个私有字段,就会抛出“Cannot read private member #keyType from an object whose class did not declare it”的错误。

2. 构造函数执行顺序冲突

即使你正确声明了私有字段,若先调用super(entries)再赋值#keyType和#valueType,super(entries)会触发Map构造函数遍历entries并调用子类的set方法——此时#keyType还未被初始化,不仅类型校验会失效,也可能引发关联错误。


正确的TypedMap实现
class TypedMap extends Map {
  // 必须在类顶层声明私有字段
  #keyType;
  #valueType;

  constructor(entries = [], keyType, valueType) {
    // 先调用super()初始化父类,不传entries避免提前触发set
    super();
    
    // 初始化私有字段(此时可正常访问this)
    this.#keyType = keyType;
    this.#valueType = valueType;

    // 手动验证并添加所有entries
    for (const [key, value] of entries) {
      this.set(key, value);
    }
  }

  set(key, value) {
    // 校验键类型
    if (!(key instanceof this.#keyType)) {
      throw new TypeError(`无效键类型:预期${this.#keyType.name},实际${typeof key}`);
    }
    // 校验值类型
    if (!(value instanceof this.#valueType)) {
      throw new TypeError(`无效值类型:预期${this.#valueType.name},实际${typeof value}`);
    }
    // 调用父类的set方法完成存储
    return super.set(key, value);
  }

  test() {
    console.log(`键类型:${this.#keyType.name},值类型:${this.#valueType.name}`);
  }
}

使用示例
// 实例化键为Number、值为String的TypedMap
const numStrMap = new TypedMap([[1, "one"], [2, "two"]], Number, String);
numStrMap.test(); // 输出:键类型:Number,值类型:String

// 正常添加符合类型的键值对
numStrMap.set(3, "three");

// 尝试添加错误类型会抛出错误
numStrMap.set("3", "three"); // TypeError: 无效键类型:预期Number,实际string

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 08:38:11