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

使用类方法执行其他类实例回调时出现NaN问题求助

问题原因

你遇到的NaN问题来自两个核心问题:

  1. BrickWall和SpikyWall中,你用BrickWall.collisionDmg这种类名访问方式,但collisionDmg是实例属性(通过this定义在构造函数里),并非类的静态属性,直接用类名访问会得到undefined。
  2. 当把brickWall.playerCollision作为回调传递给playerDamaged时,方法内部的this会丢失绑定,即使改成this.collisionDmg也会指向undefined,最终导致player.health -= undefined,结果变成NaN。
解决方案

以下是三种可行的修复方式:

方式一:绑定方法的this到实例

在传递回调时,用bind()把方法的this绑定到对应的墙实例,同时修改方法内的属性访问为this.collisionDmg:

class Player {
  constructor() {
    this.health = 100;
  }
  playerDamaged(applyDamage) {
    applyDamage(this);
  }
}

class BrickWall {
  constructor() {
    this.collisionDmg = 5;
  }
  playerCollision(player) {
    player.health -= this.collisionDmg;
  }
}

class SpikyWall {
  constructor() {
    this.collisionDmg = 25;
  }
  playerCollision(player) {
    player.health -= this.collisionDmg;
  }
}

const player = new Player();
const brickWall = new BrickWall();
const spikyWall = new SpikyWall();

// 绑定this到对应的墙实例
player.playerDamaged(brickWall.playerCollision.bind(brickWall));
player.playerDamaged(spikyWall.playerCollision.bind(spikyWall));

console.log(player.health); // 输出70

方式二:用箭头函数定义类方法

箭头函数会自动绑定当前实例的this,无需额外绑定:

class Player {
  constructor() {
    this.health = 100;
  }
  playerDamaged(applyDamage) {
    applyDamage(this);
  }
}

class BrickWall {
  constructor() {
    this.collisionDmg = 5;
  }
  // 用箭头函数定义方法,this永久绑定到实例
  playerCollision = (player) => {
    player.health -= this.collisionDmg;
  }
}

class SpikyWall {
  constructor() {
    this.collisionDmg = 25;
  }
  playerCollision = (player) => {
    player.health -= this.collisionDmg;
  }
}

const player = new Player();
const brickWall = new BrickWall();
const spikyWall = new SpikyWall();

// 直接传递方法即可
player.playerDamaged(brickWall.playerCollision);
player.playerDamaged(spikyWall.playerCollision);

console.log(player.health); // 输出70

方式三:将collisionDmg设为静态属性

如果墙的伤害值是固定常量,不需要每个实例单独修改,可以把collisionDmg改成类的静态属性,这样直接用类名访问就有效:

class Player {
  constructor() {
    this.health = 100;
  }
  playerDamaged(applyDamage) {
    applyDamage(this);
  }
}

class BrickWall {
  // 定义静态属性
  static collisionDmg = 5;
  constructor() {
    // 移除实例属性定义
  }
  playerCollision(player) {
    player.health -= BrickWall.collisionDmg;
  }
}

class SpikyWall {
  static collisionDmg = 25;
  constructor() {
    // 移除实例属性定义
  }
  playerCollision(player) {
    player.health -= SpikyWall.collisionDmg;
  }
}

const player = new Player();
const brickWall = new BrickWall();
const spikyWall = new SpikyWall();

player.playerDamaged(brickWall.playerCollision);
player.playerDamaged(spikyWall.playerCollision);

console.log(player.health); // 输出70

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:24:17