Javascript Math.pow()返回Uncaught TypeError:无法读取未定义

时间:2015-08-31 20:45:01

标签: 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), (popGrowth * 5)));

返回:

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

的jsfiddle:http://jsfiddle.net/steventang166/rrsjc79q/72/

window.addEventListener('load', function () {
    document.getElementById("buttonEndTurn").addEventListener('click', endTurn());
});
var Populations = [100, 100, 100];
var popGrowth = [0.1797];
var resourceGold = [1000, 1000, 1000];
var resourceWood = [500, 500, 500];
var minerPercent1 = 0.5;
var minerPercent2 = 0.75;
var minerPercent3 = 0.1;
var Miners = [0, 0, 0];
var Loggers = [0, 0, 0];
var endTurn = function (Populations,popGrowth,resourceGold,resourceWood,minerPercent1,minerPercent2,minerPercent3,Minners,Loggers) {
    popGrowth += Math.random;

    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)));
        
 for (var m = 0; m < 3;m++) {console.log(Populations[m])};
    
    Miners = [Math.round(Populations[0] * minerPercent1),
    Math.round(Populations[1] * minerPercent2),
    Math.round(Populations[2] * minerPercent3)];

    Loggers = [Populations[0] - Miners[0],
    Populations[1] - Miners[1],
    Populations[2] - Miners[2]];
    for (var i = 0; i < 3; i++) {
        console.log(Miners[i]);
    }
    for (var j = 0; j < 3; j++) {
        console.log(Loggers[j]);
    }

    resourceGold[0] += Miners[0] * 100;
    resourceGold[1] += Miners[1] * 100;
    resourceGold[2] += Miners[2] * 100;

    resourceWood[0] += Loggers[0] * 100;
    resourceWood[1] += Loggers[1] * 100;
    resourceWood[2] += Loggers[2] * 100;

    for (var k = 0; k < 3; k++) {
        console.log(resourceGold[k]);
    }

    for (var l = 0; l < 3; l++) {
        console.log(resourceWood[l]);
    }
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="buttonEndTurn">End Turn</button>
<canvas id="hexCanvas" width="800" height="600" style="width:800px;height:600px" />

4 个答案:

答案 0 :(得分:4)

Javascript是function scoped。因此,只要在函数中声明变量,它就会隐藏来自全局范围的同名变量。

在您的情况下,通过使变量Populations成为函数endTurn的参数,隐藏变量<{1}}:

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

因此,Populations在函数内部是undefined,而不是从全局范围保存它应该的值,它应该是:

var Populations = [100, 100, 100];

要修复错误,只需从Populations函数的参数列表中删除参数endTurn

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

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

工作演示:http://jsfiddle.net/nz3qn1dq/1/

需要进行一些调整才能让函数按预期工作:

var popGrowth = 0.1797; // <-- Changed from a 1d array to just a number

// ...

popGrowth += Math.random(); // <-- Invoking the Math.random function with brackets.

答案 1 :(得分:2)

错误告诉您Populations本身未定义。您无法使用undefined

[0]编制索引

从你的jsfiddle看,你可能会认为它会被定义为:

var Populations = [100, 100, 100];

但该数组被函数中的参数隐藏

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

但是你没有将任何参数传递给该函数,因此,函数签名中的所有参数都将默认为undefined

document.getElementById("buttonEndTurn").addEventListener('click', endTurn());

答案 2 :(得分:1)

您可以像这样定义您的函数:

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

这会创建包含所有变量名的局部变量,这会掩盖主闭包中的变量。

然后你连接这样的监听器,它立即调用函数,而不是将函数分配给按钮:

.addEventListener('click', endTurn())

你要做的是将它定义为这样,所以它从外部闭包中提取变量:

var endTurn = function () {

然后使用函数引用附加事件侦听器,如下所示:

.addEventListener('click', endTurn)

答案 3 :(得分:1)

您需要删除所有参数。 (或者你可以将外部变量作为参数传递)

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

endTurn(Populations, popGrowth, resourceGold, resourceWood, 
minerPercent1, minerPercent2, minerPercent3, Minners, Loggers);

在函数内部,参数类似于局部变量,因此在函数内部,解释器会认为&#34;人口和#34;是指未定义的参数。当我们调用我们的函数时,我们可以传入外部变量和函数,并通过函数中的本地名称来引用它们。或者,如果我们不重新声明相同的变量/函数名称,我们可以引用函数内部的外部变量。

我希望尽可能多地保留使用它们的函数范围内的局部变量。这使我更容易遍历我的代码并使我的函数/变量不会相互冲突。