为啥全局对象属性在函数后不更新?

Posted

技术标签:

【中文标题】为啥全局对象属性在函数后不更新?【英文标题】:Why a global object properties aren't updating after function?为什么全局对象属性在函数后不更新? 【发布时间】:2019-10-31 13:43:33 【问题描述】:

我正在尝试创建一个游戏,它的第一步是通过 html-select 进行角色选择。当用户通过函数(包括“开关”)选择一个选项时,先前定义的对象会重新分配他的值,我什至可以在函数内部回显这些值,但是,当我在函数外部尝试相同的值时不要正确更新。代码如下:

<html>
<head>
<script>
var selectedPlayer = 
        level: 0,
        gold: 1,
        expWorth: 0,
        classLevel: 0,
        experience: 0,
        totalHealth: 0,
        totalEnergy: 0,
        totalAttack: 0,
        totalDefense: 0,
        totalSpeed: 0,
        totalFatigue: 0
;

function switchingCharacter() 
  switch ($("#mySelect option:selected").val())     
     case "heracles":
      $("#demo2").text("You selected Heracles");
      selectedPlayer = 
        level: 2,
        gold: 2,
        expWorth: 0,
        classLevel: 0,
        experience: 0,
        totalHealth: 35,
        totalEnergy: 10,
        totalAttack: 51,
        totalDefense: 50,
        totalSpeed: 2,
        totalFatigue: 2
      ;
      break;
    case "ra":
      $("#demo2").text("You selected Ra");
      selectedPlayer = 
        level: 1,
        gold: 1,
        expWorth: 0,
        classLevel: 0,
        experience: 0,
        totalHealth: 180,
        totalEnergy: 10,
        totalAttack: 13,
        totalDefense: 8,
        totalSpeed: 2,
        totalFatigue: 2
      ;
      break;
    default:
      $("#demo2").text("You didn't select any character");
  

  $("#hp").text("HP: " + selectedPlayer.totalHealth);
  $("#attack").text("Attack: " + selectedPlayer.totalAttack);
  $("#defense").text("Defense: " + selectedPlayer.totalDefense);
  $("#energy").text("Energy: " + selectedPlayer.totalEnergy);
  $("#speed").text("Speed: " + selectedPlayer.totalSpeed);
  $("#fatigue").text("Fatigue: " + selectedPlayer.totalFatigue);
  $("#gold").text("Gold: " + selectedPlayer.gold);


function displaystats() 

  $("#level").text("Level: " + selectedPlayer.level);

//Below is something added in 2nd edition
  var testing = selectedPlayer.fatigue;
  function other() 
  $("#log").text(Math.floor(testing));
  
  other();
console.log(testing);
</script>
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
</head>

<body>

  <p>Welcome to Anime Colisseum's System Calculator.</p>

  <p>Select your character below:</p>

  <form>
    <select id="mySelect" onchange="switchingCharacter()">
    <option value="heracles">Heracles</option>  
    <option value="ra">Ra</option>
     
  </select>
  </form>

  <p id="demo" class=form-control></p>
  <p id="demo2" class=form-control></p>

</body>
<p id=hp></p>
<p id=energy></p>  
<p id=attack></p>
<p id=defense></p>
<p id=speed></p>
<p id=blocks></p>
<p id=fatigue></p>
<p id=gold></p>
<p id=level></p>
<p id=log></p>  <!-- 2edition --->
</html>  

我预计带有“id=level”的 p 元素会被更改,就像 switchCharacter() 中的其他元素一样......

我对编程相当陌生,所以很可能我忽略了一个简单但至关重要的细节。提前致谢。

现在已编辑:感谢 Zlatko 提供的答案,现在我看到我忘记在 switchingCharacter() 中调用更新统计功能。尽管如此,问题仍然存在,似乎我在switchingCharacters() 中写入的值没有正确存储在selectedCharacter 对象中,var testing = selectedPlayer.fatigue; function other() $("#log").text(Math.floor(testing)); other(); console.log(testing); 例如,通过添加这个,控制台会回显“未定义”

【问题讨论】:

【参考方案1】:

您错过了对 displaystats 的调用 - 在您的 switchingCharacter 函数结束时。这是添加了行的代码,现在显示级别。

更具体地说,您定义了一个将更新统计信息的函数。但你从来没有叫过它。这就是它不起作用的原因。


顺便说一句,您通常会将所有其他统计信息显示添加到一个函数中(无论是displaystatsrender 还是其他)。因此,您用于切换字符的代码只是切换字符(并且可能会通知某些“控制器”有更新)。您的 displaystats 代码在调用时只会显示统计信息,仅此而已。现在,这个“控制器”可以负责何时调用哪个东西 - 例如。在某个时间间隔上,或在某些动作上等。

<html>
<head>
<script>
var selectedPlayer = 
  level: 1,
  gold: 0,
  experience: 0,
  totalAttack: 0,
  totalDefense: 0,
  totalHealth: 0,
  totalEnergy: 0,
  totalSpeed: 0,
  totalBlocks: 0
;

function switchingCharacter() 
  switch ($("#mySelect option:selected").val())     
     case "heracles":
      $("#demo2").text("You selected Heracles");
      selectedPlayer = 
        level: 2,
        gold: 2,
        expWorth: 0,
        classLevel: 0,
        experience: 0,
        totalHealth: 35,
        totalEnergy: 10,
        totalAttack: 51,
        totalDefense: 50,
        totalSpeed: 2,
        totalFatigue: 2
      ;
      break;
    case "ra":
      $("#demo2").text("You selected Ra");
      selectedPlayer = 
        level: 1,
        gold: 1,
        expWorth: 0,
        classLevel: 0,
        experience: 0,
        totalHealth: 180,
        totalEnergy: 10,
        totalAttack: 13,
        totalDefense: 8,
        totalSpeed: 2,
        totalFatigue: 2
      ;
      break;
    default:
      $("#demo2").text("You didn't select any character");
  

  $("#hp").text("HP: " + selectedPlayer.totalHealth);
  $("#attack").text("Attack: " + selectedPlayer.totalAttack);
  $("#defense").text("Defense: " + selectedPlayer.totalDefense);
  $("#energy").text("Energy: " + selectedPlayer.totalEnergy);
  $("#speed").text("Speed: " + selectedPlayer.totalSpeed);
  $("#fatigue").text("Fatigue: " + selectedPlayer.totalFatigue);
  $("#gold").text("Gold: " + selectedPlayer.gold);
  displaystats();


function displaystats() 

  $("#level").text("Level: " + selectedPlayer.level);

</script>
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
</head>

<body>

  <p>Welcome to Anime Colisseum's System Calculator.</p>

  <p>Select your character below:</p>

  <form>
    <select id="mySelect" onchange="switchingCharacter()">
    <option value="heracles">Heracles</option>  
    <option value="ra">Ra</option>

  </select>
  </form>

  <p id="demo" class=form-control></p>
  <p id="demo2" class=form-control></p>

</body>
<p id=hp></p>
<p id=energy></p>  
<p id=attack></p>
<p id=defense></p>
<p id=speed></p>
<p id=blocks></p>
<p id=fatigue></p>
<p id=gold></p>
<p id=level></p>
</html> 

【讨论】:

非常感谢您的快速回答,我不敢相信我怎么会错过这样的事情。但是,仍然存在一个问题,我在switchingCharacters() 中写入的值似乎没有正确存储在selectedCharacter 对象中,var testing = selectedPlayer.fatigue; function other() $("#log").text(Math.floor(testing)); other(); console.log(testing); 例如,通过添加这个,控制台会回显“未定义”跨度> 发生这种情况是因为最初您的 testing 变量 为空。翻转下拉列表后,您需要调用该 console.log。 此外,您必须实际采用有效的道具。在播放器对象上它被称为totalFatigue,但您稍后会在分配时使用fatigue

以上是关于为啥全局对象属性在函数后不更新?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Bindinglist 在数据库更改后不更新?

为啥存储函数总是引用更新后的全局 i 变量的值?

JS全局变量是全局对象的属性,函数局部变量为啥就不是函数的属性呢?

Vue Reactivity:为啥替换对象的属性(数组)不会触发更新

Kendo Grid:外键下拉菜单在更新后不更新网格单元格

Winforms ListBox 控件在源更改后不更新