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

Node.js运行报错'Warrior未定义'及'GetAttackResult未定义'的修复求助

解决你的JavaScript OOP游戏代码错误

让我们一步步拆解你遇到的问题,先搞定核心的ReferenceError: Warrior is not defined和GetAttackResult not defined错误,顺便修正一些隐藏的语法问题:

错误原因分析与修复步骤

1. 类声明无提升,导致Warrior未定义

JavaScript里类声明不会像函数声明那样被提升。你在代码最开头直接调用了Main(),但此时Warrior和Battle类还没被解析定义,运行时自然找不到它们。

修复:把Main()的调用移到所有类定义的后面,确保类已经被加载完成后再创建实例。

2. 类方法调用方式错误,导致GetAttackResult未定义

GetAttackResult是Battle类的成员方法,你在StartFight里直接用GetAttackResult(warrior1, warrior2)调用,会被当作全局函数查找,肯定找不到。必须用this.GetAttackResult()来调用当前Battle实例的方法。

3. Math.random缺少括号,导致计算逻辑失效

Math.random是一个函数,必须加()才能生成0到1之间的随机数。你写的Math.round(Math.random * 50)会把函数本身当作数值计算,结果是NaN,攻击值和格挡值也就完全无效了。

4. 模板字符串换行的语法隐患

你在console.log里的模板字符串直接换行,虽然语法上允许,但容易引发编辑器或解释器的解析问题,建议用\n显式换行,让代码更规范。

5. 类方法的语法规范调整

ES6类语法中,类的方法不需要加function关键字,直接定义方法名即可,这样代码更符合现代JS的写法规范。

修正后的完整代码

class Warrior {
    constructor(name, health) {
        this.name = name;
        this.health = health;
    }

    Attack() {
        let attackValue = Math.round(Math.random() * 50);
        return attackValue;
    }

    Block() {
        let blockValue = Math.round(Math.random() * 10);
        return blockValue;
    }
}

class Battle {
    StartFight(warrior1, warrior2) {
        while (true) {
            if (this.GetAttackResult(warrior1, warrior2) === "Game Over") {
                console.log("Game Over");
                break;
            }
            if (this.GetAttackResult(warrior2, warrior1) === "Game Over") {
                console.log("Game Over");
                break;
            }
        }
    }

    GetAttackResult(warriorA, warriorB) {
        let warA_attack = warriorA.Attack();
        let warB_block = warriorB.Block();
        let dmg2warB = warA_attack - warB_block;
        
        // 避免出现负数伤害(格挡成功时不会回血)
        if (dmg2warB < 0) dmg2warB = 0;

        warriorB.health -= dmg2warB;

        if (dmg2warB > 0) {
            console.log(`${warriorA.name} attacks ${warriorB.name} and deals ${dmg2warB} damage.`);
            console.log(`${warriorB.name} has ${warriorB.health} health.\n`);
        } else {
            console.log(`${warriorB.name} blocked ${warriorA.name}'s attack completely!\n`);
        }

        if (warriorB.health <= 0) {
            console.log(`${warriorB.name} has died and ${warriorA.name} is victorious!`);
            return "Game Over";
        } else {
            return "Fight Again!";
        }
    }
}

function Main() {
    let apple = new Warrior("Apple", 3000);
    let microsoft = new Warrior("Microsoft", 3000);
    let battle = new Battle();
    battle.StartFight(apple, microsoft);
}

// 最后调用入口函数,确保类已定义完成
Main();

额外优化说明

  • 增加了伤害值判断,当格挡值大于攻击值时,伤害设为0,避免出现不合理的回血情况。
  • 添加了格挡成功的提示信息,让战斗过程更清晰直观。
  • 调整了变量命名(比如hi改成battle),提升代码可读性。

现在用Node.js运行这段代码,就能正常模拟战斗过程啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:23:15