我想从数组中获取一个随机数,但我收到错误:无法读取属性' length'。
//Attack arr
var attackID = [0,1];
//Start game
function start(){
console.log("Your new username is "+localuser.username+"!");
var r_atk = Math.round(Math.random()*(attackID.length-1));
if(attacks[r_atk] == 0){
punch(enemy.name);
}
else if(attacks[r_atk] == 1){
kick(enemy.name);
}
}
要查看完整代码,请点击Here然后按ctrl + u
答案 0 :(得分:0)
在定义start
数组之前,您正在调用attackID
函数。只需在attackID
内移动start()
声明,因为您无论如何都无法在其他任何地方使用它。
function start(){
var attackID = [0,1];
console.log("Your new username is "+localuser.username+"!");
var r_atk = Math.round(Math.random()*(attackID.length-1));
// ...
}
答案 1 :(得分:0)
<强>修强>
游戏的代码实际上包含两个错误。第二个错误不会立即显现,因为它被第一个错误消息遮盖了。问题是攻击既不是变量也不是属性,因为它从未在代码中声明或定义,因此在解决第一个错误后会出现ReferenceError。
Google Chrome开发者工具中显示的第一条错误消息指出:
未捕获的TypeError:无法读取属性&#39;长度&#39;未定义的
控制台指出有问题的代码是:
var r_atk = Math.round(Math.random()*(attackID.length-1));
然而,代码行本身在语法上是正确的, attackID 在函数声明之前,带有声明并定义变量的单行。您可能认为解决方案是捕获TypeError。我试过here无济于事。真正的问题涉及一个名为 hoisting 的概念,其中JavaScript变量和函数声明被移动到&#34; ...最近的范围&#34; (见here)。当 attackID 被提升时,它将评估为未定义。因此,当start()执行时,它无可救药地尝试访问未定义变量的长度属性,最终结果产生TypeError。
实用的解决方案涉及删除专门调用start()的行。由于start()的函数声明位于脚本的末尾,因此您可以将其转换为立即调用的函数表达式(IIFE)。要创建IFFE,请在start()的函数声明周围加上括号,然后使用另一对,启用该函数以自动执行以及避免提升问题。每MDN:
与函数不同,JavaScript中的函数表达式不会被挂起 声明。在定义之前,您不能使用函数表达式 他们......
现在,如果运行代码,与 attackID.length 关联的TypeError将消失,因为数组将在start()执行之前设置。
如果您运行以下代码,您将注意到 attackID.length 缺少TypeError,这允许与攻击关联的ReferenceError消息出现。
//Give user warning
console.warn("WARNING! This game is not close to being done yet\n\n\n\n");
function user(uname, HP, mana) {
this.username = uname;
this.HP = HP;
this.mana = mana;
}
function enemy(ename, HP, mana) {
this.name = ename;
this.HP = HP;
this.mana = mana;
}
var dmg = [0, 0, 0, 0, 5, 5, 5, 5, 10, 10, 10, 20, 30];
var enemy_dmg = [0, 0, 0, 0, 0, 5, 5, 5, 5, 10, 10, 10, 20, 30];
//Create user
var localuser = new user(null, 100, 100);
var enemy = new enemy("enemy1", 100, 100);
//Set user name
var newName = prompt("What do you want your username to be?");
localuser.username = newName;
//Attacks
function punch(target) { // atk 0
if (target == localuser.username) {
var r = Math.round(Math.random() * (dmg.length - 1));
localuser.HP -= dmg[r];
console.log(enemy.name + " punched you! Your HP is now " + localuser.HP + "!");
} else if (target == enemy.name) {
var r = Math.round(Math.random() * (dmg.length - 1));
enemy.HP -= dmg[r];
console.log("You punched " + target + "! His HP is now " + enemy.HP + "!");
} else {
console.warn("Make sure you put quotes around the enemy's name.");
}
}
function kick(target) { // atk 1
if (target == localuser.username) {
var r = Math.round(Math.random() * (dmg.length - 1));
localuser.HP -= dmg[r];
console.log(enemy.name + " kicked you! Your HP is now " + localuser.HP + "!");
} else if (target == enemy.name) {
var r = Math.round(Math.random() * (dmg.length - 1));
enemy.HP -= dmg[r];
console.log("You punched " + target + "! His HP is now " + enemy.HP + "!");
} else {
console.warn("Make sure you put quotes around the enemy's name.");
}
}
//Attack arr
let attackID = [0, 1];
//Start game
(function start() {
console.log("Your new username is " + localuser.username + "!");
var r_atk = Math.round(Math.random() * (attackID.length - 1));
if (attacks[r_atk] == 0) {
punch(enemy.name);
} else if (attacks[r_atk] == 1) {
kick(enemy.name);
}
})();
&#13;
相关文章:
答案 2 :(得分:0)
在您声明start()
start()
之前attackID
访问attackID
之前,正在进行此操作。在使用start()
函数之前,您应该fopen
变量。或者使用内部功能范围。
答案 3 :(得分:-1)
在您的代码中,您在第38行调用函数start()
,但您只在第74行声明并分配attackID
数组。
您必须在attackID
函数中指定start()
,或者您可以在文件的开头声明并指定所有变量。在代码之上分配将要重用的所有变量是一个很好的代码标准。