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

JavaScript类报错:无法从非声明类对象读取私有成员#privateMember

为什么调用类中存储在对象里的方法会触发私有成员访问错误?

代码示例

class Example {

  #privateMember = 123;

  // 这两个方法正常工作
  addNumber (n) { return this.#privateMember + n; }
  doAddNumber (n) { return this.addNumber(n); }

  // 此处会导致后续报错:无法从未声明该私有成员的对象读取#privateMember
  #operations = { add: this.addNumber };
  operate (n) { return this.#operations.add(n); }

}

const ex = new Example();
console.log(ex.addNumber(77));
console.log(ex.doAddNumber(77));
console.log(ex.operate(77));

报错信息

TypeError: Cannot read private member #privateMember from an object whose class did not declare it
    at Object.addNumber [as add] (<anonymous>:11:17)
    at Example.operate (<anonymous>:20:29)
    at <anonymous>:27:16
    at dn (<anonymous>:16:5449)

我的疑惑

  • addNumber可以正常执行,排除语法或拼写错误
  • doAddNumber能正常调用addNumber,排除方法间调用的问题
  • operate只是调用addNumber,按道理应该正常工作
  • this指向的是Example类的实例,该类已经声明了#privateMember

我实际场景需要用类似#operations的对象存储算法实现,现在搞不懂报错原因,求解答。


解答

核心问题是函数的this绑定丢失:

  • 当你把this.addNumber赋值给#operations.add时,只是把addNumber函数的裸引用存了起来,它和原类实例的绑定关系直接被切断了。
  • 当你通过this.#operations.add(n)调用时,函数的this会自动指向#operations这个普通对象,而不再是Example的实例。
  • JS私有成员#privateMember的访问规则很严格:只有声明它的类的实例内部,才能访问这个私有成员。#operations就是个普通对象,根本没声明过#privateMember,自然会触发报错。

修复方案

给你几种实用的解决方式:

  1. 用箭头函数绑定this
    箭头函数的this会继承定义时的上下文(也就是当前类实例),不会随调用方式改变:
#operations = { add: (n) => this.addNumber(n) };
  1. 赋值时用bind绑定实例
    通过bind把函数和实例强制绑定,确保调用时this始终指向实例:
#operations = { add: this.addNumber.bind(this) };
  1. 调用时手动指定this
    调用函数时用call或apply把this强行绑定回实例:
operate (n) { return this.#operations.add.call(this, n); }
  1. 把#operations改成getter
    每次访问时动态生成绑定好this的对象,彻底避免引用丢失问题:
get #operations() {
  return { add: this.addNumber.bind(this) };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:35:19