Javascript 出于某种原因,我的代码显示的是NaN而不是数字

Javascript 出于某种原因,我的代码显示的是NaN而不是数字,javascript,Javascript,为什么我单击按钮时得到的是NaN,而不是数字#plr1button1? 好像我不明白似的,我看了两个小时,还是不知道是什么错误 class Fighter { constructor(atk, def, hp) { this.atk = atk; this.def = def; this.hp = hp; } } var Fighter1 = new Fighter(40, 5, 100); var Fighter2 = new F

为什么我单击按钮时得到的是
NaN
,而不是数字#plr1button1? 好像我不明白似的,我看了两个小时,还是不知道是什么错误

class Fighter {
    constructor(atk, def, hp) {
        this.atk = atk;
        this.def = def;
        this.hp = hp;
    }
}
var Fighter1 = new Fighter(40, 5, 100);
var Fighter2 = new Fighter(30, 20, 100);
Fighter1.attack = function() {
    var attack1 = this.atk + (Math.floor(Math.random() * 5) - 5) - Fighter2.def;
    Fighter2.hp = Fighter2.hp - attack1;
    document.getElementById("hp2").innerHTML = Fighter2.hp;
}
Fighter2.attack = function() {
    var attack1 = this.atk + (Math.floor(Math.random() * 5) - 5) - Fighter1.def;
    Fighter1.hp = Fighter1.hp - attack1;
    document.getElementById("hp1").innerHTML = Fighter1.hp;
}
function random() {
    var randomNum =  Math.floor(Math.random() * 6) + 1;
    /*var randomNum2 =  Math.floor(Math.random() * 6) + 1;
    var randomNum3 =  Math.floor(Math.random() * 6) + 1;*/
    if (randomNum === 1) {
        document.getElementById("plr1button1").innerHTML = "Attack";
        $("#plr1button1").bind("click", Fighter1.attack);
        document.getElementById("plr2button1").innerHTML = "Attack";
    }
}

您将丢失该事件处理程序的上下文;使用
.bind
修复它

$("#plr1button1").bind("click", Fighter1.attack.bind(Fighter1));
检测它很容易:只需将断点放入
attack
方法中,并检查当as
单击
事件处理程序调用该方法时
等于什么


您的代码还有其他几个问题

首先,您可以很容易地抽象出一个函数,该函数在给定范围内生成一个随机整数,并重用它,而不是重复整个
Math.floor(Math.random…
代码段)

其次,您在
攻击
代码中混合了两个关注点,更改了(被攻击战斗机的)状态及其表示形式。通常最好将它们分开

最后,您不必要地将所有动作硬编码到两个战斗机实例中,而不是使用
prototype
存储单个函数

例如,有一种方法可以简化这一过程:

class Fighter {
    constructor(atk, def, hp) {
        this.atk = atk;
        this.def = def;
        this.hp = hp;
    }

    attack(enemy) {
        const hits = this.atk + _randomInRange(0, 5) - enemy.def;
        enemy.hp -= hits;
        enemy.render();
    }

    render() {
        // updates the representation of Fighter
    }
}

function _randomInRange(from, to) {
  return from + Math.floor( Math.random() * (to + 1 - from) );
}

下面是该方法的一个示例。

您失去了该事件处理程序的上下文;请使用
.bind
修复它

$("#plr1button1").bind("click", Fighter1.attack.bind(Fighter1));
检测它很容易:只需将断点放入
attack
方法中,并检查当as
单击
事件处理程序调用该方法时
等于什么


您的代码还有其他几个问题

首先,您可以很容易地抽象出一个函数,该函数在给定范围内生成一个随机整数,并重用它,而不是重复整个
Math.floor(Math.random…
代码段)

其次,您在
攻击
代码中混合了两个关注点,更改了(被攻击战斗机的)状态及其表示形式。通常最好将它们分开

最后,您不必要地将所有动作硬编码到两个战斗机实例中,而不是使用
prototype
存储单个函数

例如,有一种方法可以简化这一过程:

class Fighter {
    constructor(atk, def, hp) {
        this.atk = atk;
        this.def = def;
        this.hp = hp;
    }

    attack(enemy) {
        const hits = this.atk + _randomInRange(0, 5) - enemy.def;
        enemy.hp -= hits;
        enemy.render();
    }

    render() {
        // updates the representation of Fighter
    }
}

function _randomInRange(from, to) {
  return from + Math.floor( Math.random() * (to + 1 - from) );
}

这是该方法的一个实例。

这是因为您如何调用它,
这个
不是
Fighter1
,而是触发
Fighter1.attack
内部事件的元素(因为您使用的是jQuery;它将是事件对象)

当您像您一样直接调用函数时,它将使用该函数,但不会维护其通常的上下文。例如,回调中的
Fighter1.attack
Fighter1.attack()
不同

您需要做的是将函数绑定到它们各自的
this
,以便它们在内部维护它

按如下方式更改您的回调:

$("#plr1button1").bind("click", Fighter1.attack.bind(Fighter1));
然后,当它被触发时,
将按照您的预期成为
Fighter1

您还可以将函数整体绑定为不必重新绑定:

Fighter1.attack = (function() {
    var attack1 = this.atk + (Math.floor(Math.random() * 5) - 5) - Fighter2.def;
    Fighter2.hp = Fighter2.hp - attack1;
    document.getElementById("hp2").innerHTML = Fighter2.hp;
}).bind(Fighter1);

同样对
Fighter2
重复此操作。

这是因为您如何调用它,
不是
Fighter1
,而是触发
Fighter1.attack中事件的元素(因为您使用的是jQuery;它将是事件对象)

当您像您一样直接调用函数时,它将使用该函数,但不会维护其通常的上下文。例如,回调中的
Fighter1.attack
Fighter1.attack()
不同

您需要做的是将函数绑定到它们各自的
this
,以便它们在内部维护它

按如下方式更改您的回调:

$("#plr1button1").bind("click", Fighter1.attack.bind(Fighter1));
然后,当它被触发时,
将按照您的预期成为
Fighter1

您还可以将函数整体绑定为不必重新绑定:

Fighter1.attack = (function() {
    var attack1 = this.atk + (Math.floor(Math.random() * 5) - 5) - Fighter2.def;
    Fighter2.hp = Fighter2.hp - attack1;
    document.getElementById("hp2").innerHTML = Fighter2.hp;
}).bind(Fighter1);

同样对
Fighter2
重复上述操作。

这不是什么”不是真的正确…在操作码中是元素我错插了…它是jQueryGood catch再次返回的元素。我再次更新并提到了这两种情况。;“这是什么”不是真的正确…在操作代码中是元素I错戳了…它是jQueryGood catch再次返回的元素。我再次更新并提到了这两种情况。;)