Javascript 属性返回未定义的值,即使该值存在。。。?

Javascript 属性返回未定义的值,即使该值存在。。。?,javascript,Javascript,我有以下对象资源: 这看起来像一个普通的对象。 然而,我试图表现出一定数量的受欢迎程度。每次我尝试显示它时,都会得到一个NaN而不是一个数字。 我尝试返回console.logresources.popularity.upgProd;但我最终还是得到了一个未定义的结果。我不知道为什么,因为我定义了变量,但我仍然没有定义。。。 IDE或控制台中没有错误,只是在I console.log时未定义 编辑:这里是一些周围的上下文。。。这是我的更新功能,每1/7秒更新一次。此外,resources.pop

我有以下对象资源:

这看起来像一个普通的对象。 然而,我试图表现出一定数量的受欢迎程度。每次我尝试显示它时,都会得到一个NaN而不是一个数字。 我尝试返回console.logresources.popularity.upgProd;但我最终还是得到了一个未定义的结果。我不知道为什么,因为我定义了变量,但我仍然没有定义。。。 IDE或控制台中没有错误,只是在I console.log时未定义

编辑:这里是一些周围的上下文。。。这是我的更新功能,每1/7秒更新一次。此外,resources.popularity.upgProd的第一个值为0,然后下一个值变为NaN

function update() {
buffer++;
if (buffer == 35) {
checkVisibilityOnBuildings();
checkVisiblityOnUpgrades();
checkVisibilityOnResources();
buffer = 0;
} // Every 5 seconds (35 ticks) visibility will be checked and updated.

    /* Number increasing. A bit tedious but no other way to do it yet. */
    resources.number += 
   ((BUILDINGS[0].numProdBase * BUILDINGS[0].count) + //Now it's easy! Just do UPGRADES[n+1] for the next building.
    (BUILDINGS[1].numProdBase * BUILDINGS[1].count) +
    (BUILDINGS[2].numProdBase * BUILDINGS[2].count) +
    (BUILDINGS[3].numProdBase * BUILDINGS[3].count));
    //Science gained per tick. Var used to make the "scienceProductionTotalDisp" work properly
    var scienceTotalPerTick = 
    (BUILDINGS[2].sciProdBase * BUILDINGS[2].count) + 
    (BUILDINGS[3].sciProdBase * BUILDINGS[3].count);

    resources.science += scienceTotalPerTick;



    //Display vars for html so that rounding errors don't happen.
    var numDisp = Math.floor(resources.number);
    var sciDisp = Math.floor(resources.science * 100) / 100;
    var popDisp = Math.floor(resources.popularity.amount * 100) / 100;
    console.log(Number(resources.popularity.upgProd));
    var moneyTotalPerTick = Math.pow(resources.number, (1/(player.moneyRatio))) + 1; //Cash flow per 143ms (7n for total / sec ish)
    var popularityTotalPerTick = (Number(resources.popularity.upgProd)) + 0;
    resources.popularity += popularityTotalPerTick;
    console.log(resources.popularity.upgProd);
    resources.money += moneyTotalPerTick;
    getId('moneyProductionTotalDisp').innerHTML = numFormat(Math.floor(moneyTotalPerTick * 7));
    getId('moneyDisp').innerHTML = numFormat(Math.round(resources.money * 100) / 100);
    getId('numberDisp').innerHTML = numFormat(numDisp);
    getId('scienceDisp').innerHTML = numFormat(sciDisp);
    getId('popularityDisp').innerHTML = numFormat(popDisp);
    getId('scienceProductionTotalDisp').innerHTML = 
numFormat(Math.floor(scienceTotalPerTick * 700) / 100);
    getId('popularityProductionTotalDisp').innerHTML = 
numFormat(Math.floor(popularityTotalPerTick * 700) / 100);
谢谢大家!

尝试使用console.logresources[popularity][upgProd]

以下是您的问题:

resources.popularity+=popularityTotalPerTick

受欢迎是一个目标,而这并不是你想要的

由于您用一个值添加的对象的结果覆盖它,因此您将其指定为字符串[object object]9,其中最后一个数字是popularityTotalPerTick中的数字

由于您使用的是Numberxin console.logNumberresources.popularity.upgProd;,所以您没有得到一个数字;。你为什么这么做

每次调用函数时,getId都会在dom中查找元素吗?对象是否已更改,或者是否每秒查询同一元素的DOM 7次

关于代码中其他内容的一些想法:

resources.number +=
    ((BUILDINGS[0].numProdBase * BUILDINGS[0].count) +
        (BUILDINGS[1].numProdBase * BUILDINGS[1].count) +
        (BUILDINGS[2].numProdBase * BUILDINGS[2].count) +
        (BUILDINGS[3].numProdBase * BUILDINGS[3].count));
我假设建筑物是一个包含所有建筑物的数组,并且您希望计算数组中所有建筑物的数量。有一个函数:它接受两个参数:函数和起始值:

resources.number += // do you really want += here and not just = ?
  BUILDINGS.reduce( (sum, item) => sum + (item.numProdBase * item.count), 0 );
如果您不熟悉箭头功能,可以将其替换为:

function (sum, item) { return sum + (item.numProdBase * item.count) }
我不知道为什么你只为两栋楼做这个,而不是所有的,但是你也可以在这里使用reduce

请注意,要切片的参数是begin-to-end-end-not-include,因此2,4给出了元素2和3

有了这部分代码

getId('moneyProductionTotalDisp').innerHTML = numFormat(Math.floor(moneyTotalPerTick * 7));
getId('moneyDisp').innerHTML = numFormat(Math.round(resources.money * 100) / 100);
getId('numberDisp').innerHTML = numFormat(numDisp);
getId('scienceDisp').innerHTML = numFormat(sciDisp);
getId('popularityDisp').innerHTML = numFormat(popDisp);
我假设getId是一个函数,它通过document.getElementById或document.querySelector获取元素,并且对每一帧执行此操作,每次都会获得相同的元素。现在假设这个元素是一个盒子,我要求你从世界另一边的仓库里得到它。当你送箱子的时候,我打开箱子,把里面的东西放回世界另一边的仓库。当你回来的时候,我要求你再次得到同样的盒子,你现在必须再次去世界的另一边。。。当你回来的时候,故事会重复

我的观点是,每次去世界的另一端获取相同的框,或者每次更新时从DOM获取相同的元素,都是非常浪费的。您可以通过在开始更新之前查找元素一次来缓存元素,并且可以将结果放入对象中:

function getElementsToUpdate() {
  return {
    moneyProductionTotalDisp: getId('moneyProductionTotalDisp'),
    moneyDisp: getId('moneyDisp'),
    // and so on...
  }
}
如果将对象中的属性命名为与id相同的名称,则可以将所有名称放入一个数组中,然后将其缩减为一个对象。这样可以节省一些打字时间,并且由于名称拼写错误,很难找到bug:

function getElementsToUpdate() {
  return [
    'moneyProductionTotalDisp',
    'moneyDisp',
    'numberDisp',
    'scienceDisp',
    'popularityDisp',
    // and so on....
  ].reduce(
    (out, id) => { out[id] = getId(id); return out; }, {}
  )
}
注意:此函数应在启动时运行一次,而不是在每次更新帧时运行。它返回一个包含元素的对象

在代码中的某个地方,我假设您使用来调用update函数。由于setInteval可以获取将提供给被调用函数的额外参数,因此可以执行以下操作:

var timerHandle = setInterval( update, 1000/7, getElementsToUpdate() );
其中update是函数,1000/7为您提供每秒7次的间隔,getElementsToUpdate是一个函数,该函数进行耗时的调用,以从DOM获取元素一次

您需要更改update函数以获取一个参数,该参数的名称并不重要,但应该简短且具有描述性,因此我使用elem。这是getElementsToUpdate与所有html元素一起返回的对象

function update(elem) {
  // ... your code ....

  // Old code, that makes an expensive lookup into the DOM, and start a HTML parser.
  // getId('numberDisp').innerHTML = numFormat(numDisp);

  // New code, that gets the pre-looked up element and set the text.  
  elem.numberDisp.textContent = numFormat(numDisp);
}

当插入的不是html时,我不喜欢使用.innerHTML。如果不是html,请始终使用.textContent。在这种情况下,最好使用-element并设置.value属性。

问题似乎不在您发布的代码中-资源是否真的是静态地立即填充的?您可以发布更多关于contextconsole.logresources.popularity;?当您得到NaN时?您确定打印输出时范围中没有不同的resources变量。在调用console.log之前,您是否对资源进行了任何修改,例如将其传递到函数中?console.logresources.popularity得到了什么?这是javascript,而不是php,完全可以,我更喜欢写resources.popularity.upgprod非常感谢!是的,对象每1/7秒改变一次,因为每次勾号你都会得到一定数量的每个资源,然后这些资源就会被反射出来。@JackGoodman拥有你用getId chan得到的对象
每1/7秒一次?或者你正在执行一个非常耗时的函数来一遍又一遍地获取同一个元素…?对象没有改变,只有它的一个属性的值。我该如何解决这个问题?如果你说的是html对象,而我认为你不是?然后每秒更新7次。javascript对象除了我的RESOURCES对象中每个资源的属性外不会改变。因此,当我使用函数getElementsToUpdate时,我是否必须为它返回的内容创建一个对象,并在每一帧调用该对象?目前,只要运行一次函数,每次执行某个操作时,它都会更新。此外,@some在使用上一个函数时,我会收到一个赋值为右值的错误。看看为什么现在是这样。
function getElementsToUpdate() {
  return [
    'moneyProductionTotalDisp',
    'moneyDisp',
    'numberDisp',
    'scienceDisp',
    'popularityDisp',
    // and so on....
  ].reduce(
    (out, id) => { out[id] = getId(id); return out; }, {}
  )
}
var timerHandle = setInterval( update, 1000/7, getElementsToUpdate() );
function update(elem) {
  // ... your code ....

  // Old code, that makes an expensive lookup into the DOM, and start a HTML parser.
  // getId('numberDisp').innerHTML = numFormat(numDisp);

  // New code, that gets the pre-looked up element and set the text.  
  elem.numberDisp.textContent = numFormat(numDisp);
}