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

Uncaught TypeError: 无法设置私有字段:对象不是正确的类问题求助

解决Uncaught TypeError: can't set private field: object is not the right class错误

这个问题我之前也踩过坑,核心原因是私有方法#tick的上下文(this指向)丢失了,我来给你一步步拆解:

错误根源

当你在startTimer里执行setInterval(this.#tick, this.#timeBetweenTicks)时,你只是把#tick方法本身作为参数传给了setInterval,并没有带上它的上下文。setInterval在执行回调时,默认会把this绑定到全局的Window对象(非严格模式下)。

而JavaScript的私有字段(比如#currentTime)是严格绑定到所属类的实例的——只有CyclingTimer的实例才能访问这些私有成员。Window对象显然不是CyclingTimer的实例,所以当#tick里尝试访问this.#currentTime时,就会抛出你看到的错误,这也和你调试时看到#tick里的this是Window对象完全吻合。

而startTimer里的this是正常的,因为你是通过CyclingTimer实例调用startTimer方法的,此时this自然指向实例本身。

解决方法

有三种常用的方式可以修复这个问题,核心都是让#tick执行时的this指向CyclingTimer实例:

方法1:用箭头函数包裹回调

箭头函数会继承外层作用域的this,这里就是CyclingTimer实例:

startTimer() {
  // 此处调试打印this时输出CyclingTimer对象,符合预期
  setInterval(() => this.#tick(), this.#timeBetweenTicks);
}

方法2:用bind绑定this

通过bind方法手动把#tick的this绑定到实例:

startTimer() {
  // 此处调试打印this时输出CyclingTimer对象,符合预期
  setInterval(this.#tick.bind(this), this.#timeBetweenTicks);
}

方法3:在构造函数里提前绑定

如果这个方法会被多次使用,可以在构造函数里一次性绑定好this:

constructor(maximumTime, timeBetweenTicks) {
  super();
  this.#maximumTime = maximumTime;
  this.#timeBetweenTicks = timeBetweenTicks;
  this.#currentTime = 1;
  // 提前绑定this,后续调用#tick时都会指向当前实例
  this.#tick = this.#tick.bind(this);
}

startTimer() {
  setInterval(this.#tick, this.#timeBetweenTicks);
}

额外说明

JavaScript的私有成员(#开头的字段/方法)有严格的访问限制,不仅外部无法访问,即使是继承的子类也不能直接访问父类的私有成员。所以确保this指向正确的类实例,是访问私有成员的前提。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:02:27