如何动态命名和创建子对象属性?
Posted
技术标签:
【中文标题】如何动态命名和创建子对象属性?【英文标题】:How to dynamically name & create sub-object properties? 【发布时间】:2020-10-24 18:19:15 【问题描述】:我有一个对象,稍后我将其写入 JSON 进行存储。这个特殊的项目是为我正在制作的 rpg-bot 生成敌人。我有一个关于敌人统计数据的“动物寓言”,我正在尝试生成多个敌人以进入遭遇战。
这是现在的代码 sn-p:
SpawnEncounter(message, [0, 2, 5, 1], characterInfoJSON, userID, ServerPrefix)
function SpawnEncounter(message, EnemiesIndicies, InfoFile, user, ServerPrefix)
// bestiary is a json containing monster statistics. their keys are numbers
let bestiary = JSON.parse(fs.readFileSync("./bestiary.json", "utf8"));
let encounterIntro = [];
InfoFile[user].CurrentEncounter = ;
InfoFile[user].CurrentEncounter.Target = 0;
InfoFile[user].CurrentEncounter.Enemies = ;
// EnemiesIndecies is an array of keys, referring to specific monsters in the bestiary
for (const item in EnemiesIndicies)
// Copy the monster stats into one enemy in the encounter
InfoFile[user].CurrentEncounter.Enemies[item] = bestiary[EnemiesIndicies[item]];
// Add a Modifiers object to the enemy
InfoFile[user].CurrentEncounter.Enemies[item].Modifiers =
StrMod: 0,
DefMod: 0,
AttackSpeedMod: 0,
ACMod: 0,
DmgMod: 0,
CritMod: 0
// push the name of the enemy to the list of all enemies that will spawn
encounterIntro.push(bestiary[EnemiesIndicies[item]].Name);
// store the encounter once complete
fs.writeFile("./playerinfo.json", JSON.stringify(InfoFile), (err) =>
if (err) console.log(err)
);
// display the new encounter
let LastEnemy = encounterIntro.pop()
if (encounterIntro.length === 0)
message.channel.send(`All of a sudden, a $LastEnemy appears!\nTo attack it, use \`\`$ServerPrefixattack\`\``);
else if (encounterIntro.length >= 1)
message.channel.send(`All of a sudden, a $encounterIntro.join(", ") and a $LastEnemy appears!\nTo attack it, use \`\`$ServerPrefixattack\`\``);
我希望创建的是这样的:
MyID:
CurrentEncounter:
Target: 0
Enemies:
0: insert enemy 0's stats + modifiers,
1: insert enemy 2's stats + modifiers,
2: insert enemy 5's stats + modifiers,
3: insert enemy 1's stats + modifiers
我意识到这已经被大大简化了,但我希望它能够理解这一点。
我的问题是,每次我运行这个程序并产生一个遭遇时,它总是说应该出现的敌人都被称为“未定义”。
我在写入 JSON 后检查了它,对象的结构是正确的,直到 Enemies。它显示有一个归于 Enemies 的对象,但它是空的。里面什么都没有。
这告诉我,我在生成敌人或将信息分配给敌人属性的方式上有问题,但我无法确定。更糟糕的是,没有错误消息可以关闭。这一定意味着我的语法是正确的,但它没有提取动物寓言信息,或者它没有正确编写它......
谁能告诉我哪里出了问题,或者更好:提出一个更好的解决方案?
【问题讨论】:
【参考方案1】:for (const item in EnemiesIndicies)
// Copy the monster stats into one enemy in the encounter
InfoFile[user].CurrentEncounter.Enemies[item] = bestiary[EnemiesIndicies[item]];
// Add a Modifiers object to the enemy
InfoFile[user].CurrentEncounter.Enemies[item].Modifiers =
StrMod: 0,
DefMod: 0,
AttackSpeedMod: 0,
ACMod: 0,
DmgMod: 0,
CritMod: 0
;
// push the name of the enemy to the list of all enemies that will spawn
encounterIntro.push(bestiary[EnemiesIndicies[item]].Name);
您正在使用 For->In 循环...该循环的每次迭代,“item”都是与 EnemiesIndicies 数组不同的值...它不是数组中当前项的索引。当你这样做时:
InfoFile[user].CurrentEncounter.Enemies[item] = bestiary[EnemiesIndicies[item]];
和:
encounterIntro.push(bestiary[EnemiesIndicies[item]].Name);
您正在使用 item 作为 EnemiesIndicies 中的索引...很有可能作为 EnemiesIndicies 中存储的值之一的 item 的值超出了数组的条目数...因此它不是有效索引......即使它是一个有效的索引,它也不是值本身的索引......它所写的唯一方法是:EnemiesIndicies[0] 为 0,EnemiesIndicies[1] 为 1,和 EnemiesIndicies[2] 是 2,等等......
考虑使用标准的 for 循环:
let item = 0;
for (item = 0; item < EnemiesIndicies.length; item++)
// Copy the monster stats into one enemy in the encounter
InfoFile[user].CurrentEncounter.Enemies[item] = bestiary[EnemiesIndicies[item]];
// Add a Modifiers object to the enemy
InfoFile[user].CurrentEncounter.Enemies[item].Modifiers =
StrMod: 0,
DefMod: 0,
AttackSpeedMod: 0,
ACMod: 0,
DmgMod: 0,
CritMod: 0
;
// push the name of the enemy to the list of all enemies that will spawn
encounterIntro.push(bestiary[EnemiesIndicies[item]].Name);
这样做... item 始终是 EnemiesIndicies 中值的索引。
【讨论】:
不幸的是,这并没有做到。我复制了你的建议来替换我的 for-in 循环,它仍然说“突然间,出现了一个未定义的内容!” 它仍在应用正确的结构,但它没有向 Enemies 写入任何内容。 在循环中,做一个console.log(item); console.log(EnemiesIndicies[item]); console.log(bestiary[EnemiesIndicies[item]]);看看会返回什么...确保您确实传递了您认为自己的数据... 我刚刚完成了您建议的控制台日志,但没有任何内容打印到控制台...【参考方案2】:事实证明,在一种情况下,当我调用 SpawnEncounter() 时,我只是将 EnemiesIncdecies 作为一个数字而不是一个数字数组传入(即使数组中只有一个数字)。传入一个数字数组后,问题自行解决,代码现在可以正常工作了。
【讨论】:
讽刺谁会想到两个括号(“[ ]”)会导致长达一个月的问题!以上是关于如何动态命名和创建子对象属性?的主要内容,如果未能解决你的问题,请参考以下文章