使用类方法执行其他类实例回调时出现NaN问题求助
问题原因
你遇到的NaN问题来自两个核心问题:
BrickWall和SpikyWall中,你用BrickWall.collisionDmg这种类名访问方式,但collisionDmg是实例属性(通过this定义在构造函数里),并非类的静态属性,直接用类名访问会得到undefined。- 当把
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
相关产品推荐
相关产品推荐

