Javascript Math.pow()返回未捕获的TypeError:无法读取属性';0';未定义的

Javascript Math.pow()返回未捕获的TypeError:无法读取属性';0';未定义的,javascript,Javascript,我似乎不明白为什么会这样: Populations[0] = Math.round(Math.pow((Populations[0] * Math.E), (popGrowth * 5))); Populations[1] = Math.round(Math.pow((Populations[1] * Math.E), (popGrowth * 5))); Populations[2] = Math.round(Math.pow((Populations[2] * Math.E), (popGr

我似乎不明白为什么会这样:

Populations[0] = Math.round(Math.pow((Populations[0] * Math.E), (popGrowth * 5)));
Populations[1] = Math.round(Math.pow((Populations[1] * Math.E), (popGrowth * 5)));
Populations[2] = Math.round(Math.pow((Populations[2] * Math.E), (popGrowth * 5)));
返回以下内容:

未捕获的TypeError:无法读取未定义的属性“0”

JSFiddle:

window.addEventListener('load',function(){
document.getElementById(“ButtonnendTurn”).addEventListener('click',endTurn());
});
变量总体=[100100100];
var popGrowth=[0.1797];
var resourceGold=[100010001000];
var resourceWood=[500500500];
var 1=0.5;
var 2=0.75;
var 3=0.1;
var=[0,0,0];
变量记录器=[0,0,0];
var endTurn=函数(种群、popGrowth、resourceGold、resourceWood、矿工百分比1、矿工百分比2、矿工百分比3、矿工、伐木工人){
popGrowth+=Math.random;
人口[0]=Math.round(Math.pow((人口[0]*Math.E),(人口增长*5));
人口[1]=Math.round(Math.pow((人口[1]*Math.E),(人口增长*5));
人口[2]=Math.round(Math.pow((人口[2]*Math.E),(人口增长*5));
对于(var m=0;m<3;m++){console.log(Populations[m])};
矿工=[Math.round(人口[0]*minerPercent1),
数学四舍五入(总体[1]*2),
数学圆(总体[2]*3];
伐木工人=[人口[0]-矿工[0],
人口[1]-矿工[1],
人群[2]-矿工[2];
对于(变量i=0;i<3;i++){
控制台日志(矿工[i]);
}
对于(var j=0;j<3;j++){
控制台日志(记录器[j]);
}
resourceGold[0]+=矿工[0]*100;
resourceGold[1]+=矿工[1]*100;
resourceGold[2]+=矿工[2]*100;
resourceWood[0]+=伐木工人[0]*100;
resourceWood[1]+=伐木工人[1]*100;
resourceWood[2]+=伐木工人[2]*100;
对于(var k=0;k<3;k++){
console.log(resourceGold[k]);
}
对于(var l=0;l<3;l++){
控制台日志(resourceWood[l]);
}
};

末端转弯

错误告诉您,
人口
本身未定义。您不能使用
[0]


通过查看您的JSFIDLE,您可能会认为它的定义是因为:

var Populations = [100, 100, 100];
但该数组被函数中的参数隐藏

var endTurn = function (Populations,popGrowth,resourceGold,resourceWood,minerPercent1,minerPercent2,minerPercent3,Minners,Loggers) {
但是您没有向该函数传递任何参数,因此,函数签名中的所有参数都将默认为
undefined

document.getElementById("buttonEndTurn").addEventListener('click', endTurn());
Javascript是。因此,只要在函数中声明变量,它就会从全局范围中隐藏具有相同名称的变量

在您的例子中,通过将变量
Populations
作为函数
endTurn
的参数来隐藏该变量:

var endTurn = function (Populations,popGrowth,resourceGold,resourceWood,minerPercent1,minerPercent2,minerPercent3,Minners,Loggers) {
因此,
Populations
在函数中是
未定义的
,而不是保存全局范围中的值,该值应为:

var Populations = [100, 100, 100];
要修复此错误,只需从
endTurn
函数的参数列表中删除参数
Populations

此外,您正在调用函数
endTurn
,同时尝试将其绑定到
click
事件。你可能想写:

document.getElementById("buttonEndTurn").addEventListener('click', endTurn); // <-- without the brackets

document.getElementById(“ButtonnendTurn”).addEventListener('click',endTurn);// 您可以这样定义函数:

var endTurn = function (Populations,popGrowth,resourceGold,resourceWood,minerPercent1,minerPercent2,minerPercent3,Minners,Loggers) {
.addEventListener('click', endTurn)
这将创建具有所有这些变量名的局部变量,从而使主闭包中的变量黯然失色

然后像这样附加侦听器,它会立即调用函数,而不是将函数分配给按钮:

.addEventListener('click', endTurn())

相反,您要做的是这样定义它,因此它从外部闭包中提取变量:

var endTurn = function () {
然后使用函数引用连接事件侦听器,如下所示:

var endTurn = function (Populations,popGrowth,resourceGold,resourceWood,minerPercent1,minerPercent2,minerPercent3,Minners,Loggers) {
.addEventListener('click', endTurn)

您需要删除所有参数。(也可以将外部变量作为参数传入)

或者,您可以在调用函数时将所有变量作为参数传递到函数中。函数调用如下所示:

endTurn(Populations, popGrowth, resourceGold, resourceWood, 
minerPercent1, minerPercent2, minerPercent3, Minners, Loggers);
在函数内部,参数类似于局部变量,因此在函数内部,解释器认为“总体”是指未定义的参数。当我们调用函数时,我们可以传入外部变量和函数,并在函数中通过它们的本地名称引用它们。或者,如果我们不重新声明相同的变量/函数名,我们可以只引用函数中的外部变量


我更喜欢尽可能多地将局部变量限定在使用它们的函数中。这使我更容易遍历代码,并防止函数/变量相互冲突

亲爱的Shain,欢迎来到Stack Overflow!堆栈溢出问题的答案有望为问题提供实质性的解决方案,不仅可以解释要更改什么,还可以说明为什么需要进行更改,以便原始海报可以从错误中吸取教训。有关更多详细信息,请参阅。谢谢我觉得我回答得很好。。。让我知道我的帖子有什么特别的问题。在我发表评论的时候,你的回答只是一句简短的话。看来你已经修改了你的答案,使之更加充实。谢谢您的回答,给您带来不便,敬请原谅@StevenTang为了回答你的问题,我在你的代码中看到了更多的错误:(1)
Math.random
应该是
Math.random()
,这可能是造成NaN值的原因。(2) 在第25行,有一个杂散的闭合方括号。您的代码中可能还有一些小错误-我建议在代码中添加更多的
控制台。在代码中记录
语句以帮助调试它(或者如果您愿意的话,可以使用Chrome调试器!),并从顶部取下它,消除您发现的每一个异常情况。祝你好运