单击NaN
按钮时,为什么我会收到#plr1button1
而不是数字?
就像我不理解它我看了2个小时,我仍然无法弄清楚错误。
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";
}
}
答案 0 :(得分:3)
您丢失了该事件处理程序的上下文;使用.bind
来修复它。
$("#plr1button1").bind("click", Fighter1.attack.bind(Fighter1));
很容易检测到它:只需将断点放入attack
方法,然后检查this
等于何时调用方法click
事件处理程序。
您的代码还有其他几个问题。
首先,您可以轻松地抽象一个在给定范围内生成随机整数的函数 - 并重复使用它而不是重复整个Math.floor(Math.random...
代码段。
其次,你在attack
代码中混合了两个问题,改变了状态(受攻击的战斗机)及其表示。分开这些通常会更好。
最后,您不必要地硬编码了两个Fighter实例中的所有操作 - 而不是使用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) );
}
此处采用small (and incomplete) demo方法。
答案 1 :(得分:1)
这是因为你如何称呼它,this
不是Fighter1
,它是触发事件的元素(因为你正在使用jQuery; vanilla) JS它将是Fighter1.attack
内的事件对象。
当您直接调用某个功能时,它会使用该功能,但不会维护它的常用环境。即,回调中的Fighter1.attack
与Fighter1.attack()
不同。
您需要做的是将函数绑定到各自的this
,以便将它们保留在内部。
更改您的回调:
$("#plr1button1").bind("click", Fighter1.attack.bind(Fighter1));
然后,当它被触发时,this
将按照您的意图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
。