我相当肯定这是一个简单的错误,但我很困惑为什么这不会起作用。我在访问属性时无法找到有关连续使用多个括号的任何文档。这是我的代码的一部分,它创建了一个链接,当点击它时运行" dropItem"功能:
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
dropButton.onclick= function() {dropItem(dropCat, dropDest)};
" dropItem" 功能:
var dropItem = function(category, droppedItem) {
player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1; };
我得到一个"无法读取属性'螺丝刀'未定义" 错误。如何正确地通过这个?两个属性都需要是变量才能工作。由于多个括号,这是一个错误吗?
编辑:
我意识到我忘了包含播放器对象的结构,这对于理解为什么我需要传递一个带点标记的类别至关重要:
var player = {
"health": 100,
"hydration": 100,
"hunger": 100,
"energy": 100,
"inventory": {
"supplies": {
"tools": {
"screwdriver": {
"amount": 0,
"condition": 0
}
},
"buldingMaterials": {
"wood": {
"amount": 0,
"condition": 0
}
}
},
"aidPacks": {
"healthPacks": 0
}
}
}
这就是为什么我需要能够使用相同的功能访问player.inventory。 supplies.tools 和player.inventory。 aidPacks.healthpacks 。
答案 0 :(得分:1)
在查看了 lightstalker89 的代码后,我意识到我的问题不是括号,而是传递的类别不是在中间解析点符号,因此保持为“耗材” .tools“而不是完全分离。但是,由于播放器对象的结构方式,我需要能够传递点标记类别,所以我拆分字符串:
var player = { "inventory": { "supplies": { "tools" : { "screwdriver" : { "amount" : 1}}}}};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function dropItem(category, droppedItem) {
if(category.indexOf(".") > 0) {
var newCat = category.split(".");
var cat1 = newCat[0];
var cat2 = newCat[1];
player.inventory[cat1][cat2][droppedItem].amount = player.inventory[cat1][cat2][droppedItem].amount - 1;
alert(player.inventory[cat1][cat2][droppedItem].amount);
}else {
player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1;
alert(player.inventory[category][droppedItem].amount);
}
}
dropItem(dropCat, dropDest);
这是JSFiddle:https://jsfiddle.net/j7g0d8kz/
再一次,非常感谢@ lightstalker89让我意识到自己的错误。
答案 1 :(得分:1)
您可以使代码更通用,更简单。当你有两个以上的类别时,这很有用 - 那么你不需要使用[0]和1 - 这里是代码:
var player = { "inventory": { "supplies": { "tools" : { "screwdriver" : { "amount" : 1}}}}};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function getProperty(obj, str) {
return str.split(".").reduce(function(o, x) { return o[x] }, obj);
}
function dropItem(category, droppedItem) {
var accessString = dropCat + "." + droppedItem;
getProperty(player.inventory, accessString).amount -= 1;
alert(getProperty(player.inventory, accessString).amount);
}
dropItem(dropCat, dropDest);
答案 2 :(得分:0)
你的玩家对象是什么样子的?当您想要更改属性时,它是否为空对象。
基本上你可以像你一样使用多个括号。
如果播放器对象没有所需的属性,那么您的代码应如下所示:
var player = {};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function dropItem(category, droppedItem) {
if(!player.inventory){
player.inventory = {};
}
if(!player.inventory[category]){
player.inventory[category] = {};
}
if(!player.inventory[category][droppedItem]){
player.inventory[category][droppedItem] = { amount: 0};
}
player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1;
}
dropItem(dropCat, dropDest);
alert(JSON.stringify(player));
alert(player.inventory[dropCat][dropDest].amount);
这是小提琴:https://jsfiddle.net/csqbjnd7/1/
如果玩家对象存在,您可以使用多个括号。代码应如下所示:
var player = { "inventory": { "supplies.tools" : { "screwdriver" : { "amount" : 1}}}};
var dropDest = "screwdriver";
var dropCat = "supplies.tools";
function dropItem(category, droppedItem) {
player.inventory[category][droppedItem].amount = player.inventory[category][droppedItem].amount - 1;
}
dropItem(dropCat, dropDest);
alert(player.inventory[dropCat][dropDest].amount);
alert(JSON.stringify(player));