数组内的循环抛出Uncaught TypeError:无法读取属性' 1'未定义的

时间:2017-01-31 13:51:09

标签: javascript jquery arrays typeerror

我正在努力使这个简单的战利品系统工作,但我不断得到这个TypeError,我已经尝试了我能想到的一切。

我在下面添加的代码中解释了所有内容。它昨天工作但似乎今天不再工作......

以下是JS文件中的代码:

console.info("Working!");
var items;
//here I get the json
$.getJSON('js/items.json', function(data) {
    return items = data;
});
//run the function cuz laziness to put it every time in the console
loot();

function loot() {
  //these are the drops from the mob
  const ids = [1, 2, 3, 4, 5, 6, 7];
  //define a random number to see what loot it drops
  let rand = Math.floor((Math.random() * 100) + 1);
  var loot;
  //if the chance is between 1 and 5(including them) do that
  if (rand >= 1 && rand <= 5) {
    var legends = [];
    //here I loop inside the ids constant to see what items are legendary and if they are push them to the legends array
    for (var id in ids) {
      //HERE IS THE PROBLEM I get Uncaught TypeError here and I have tried everything
      if (items[ids[id]].rarity == "Legendary") {
        legends.push(ids[id]);
      };
    };
    console.log(`legends: ${legends}`);
    //then I random the items inside legends array to get the loot
    loot = legends[Math.floor(Math.random() * legends.length)];
  };
  console.warn(`You looted a ${items[loot].name} | ${items[loot].rarity}`);
};

这是JSON文件:

{
  "1": {
    "id": 1,
    "name": "Sword of Heaven",
    "rarity": "Legendary"
  },
  "2": {
    "id": 2,
    "name": "Wooden Sword",
    "rarity": "Common"
  },
  "3": {
    "id": 3,
    "name": "Glass of the Gods",
    "rarity": "Rare"
  },
  "4": {
    "id": 4,
    "name": "Minor HP Potion",
    "rarity": "Common"
  },
  "5": {
    "id": 5,
    "name": "The Enchiridion!",
    "rarity": "Legendary"
  },
  "6": {
    "id": 6,
    "name": "Major MP Potion",
    "rarity": "Rare"
  },
  "7": {
    "id": 7,
    "name": "Helm of the Forsaken",
    "rarity": "Rare"
  }
}

2 个答案:

答案 0 :(得分:3)

尝试将您的loot功能转移到异步getJson的回调中:

console.info("Working!");
var items;
//here I get the json
$.getJSON('js/items.json', function(data) {
    items = data;
    //run the function cuz laziness to put it every time in the console
    loot();
});

如果您在此回调之外运行它,则items变量尚未填充

如果你想用作函数,把AJAX调用移到loot函数中,存储结果并确保只运行一次:

function lootRun(refresh) {
  // use self in order to reach it from anonymous callback
  var self = this; 
  if (!self.items || refresh) {
    $.getJSON('js/items.json', function(data) {
      // kind of inner functional cache
      self.items = data; 
      loot(self.items);
    });
  }
  else {
    loot(self.items);
  }
}

function loot(items) {
  //these are the drops from the mob
  const ids = [1, 2, 3, 4, 5, 6, 7];
  //define a random number to see what loot it drops
  let rand = Math.floor((Math.random() * 100) + 1);
  var loot;
  //if the chance is between 1 and 5(including them) do that
  if (rand >= 1 && rand <= 5) {
    var legends = [];
    //here I loop inside the ids constant to see what items are legendary and if they are push them to the legends array
    ids.forEach(function(id) {
      //HERE IS THE PROBLEM I get Uncaught TypeError here and I have tried everything
      if (items[id].rarity == "Legendary") {
        legends.push(id);
      };
    });

    console.log(`legends: ${legends}`);
    //then I random the items inside legends array to get the loot
    loot = legends[Math.floor(Math.random() * legends.length)];
    console.warn(`You looted a ${items[loot].name} |     ${items[loot].rarity}`);
  };
};

现在,您可以通过loot运行主lootRun功能,如果要从服务器刷新数据,则将true传递给lootRun

答案 1 :(得分:1)

需要注意的一些事项 - getJson是异步的,因此项目可能未定义。将其移动到getJson回调中。此外,您正在尝试获取未定义项目的名称。您需要将最后一个console.log语句移动到if语句中,以便您不使用loot(未定义)来索引数组。

var data = {
  "1": {
    "id": 1,
    "name": "Sword of Heaven",
    "rarity": "Legendary"
  },
  "2": {
    "id": 2,
    "name": "Wooden Sword",
    "rarity": "Common"
  },
  "3": {
    "id": 3,
    "name": "Glass of the Gods",
    "rarity": "Rare"
  },
  "4": {
    "id": 4,
    "name": "Minor HP Potion",
    "rarity": "Common"
  },
  "5": {
    "id": 5,
    "name": "The Enchiridion!",
    "rarity": "Legendary"
  },
  "6": {
    "id": 6,
    "name": "Major MP Potion",
    "rarity": "Rare"
  },
  "7": {
    "id": 7,
    "name": "Helm of the Forsaken",
    "rarity": "Rare"
  }
};

// here I get the json
$.getJSON('js/items.json', function(data) {
  loot(data);
});

function loot(items) {
  //these are the drops from the mob
  const ids = [1, 2, 3, 4, 5, 6, 7];
  //define a random number to see what loot it drops
  let rand = Math.floor((Math.random() * 100) + 1);
  var loot;
  //if the chance is between 1 and 5(including them) do that
  if (rand >= 1 && rand <= 5) {
    var legends = [];
    //here I loop inside the ids constant to see what items are legendary and if they are push them to the legends array
    ids.forEach(function(id) {
      //HERE IS THE PROBLEM I get Uncaught TypeError here and I have tried everything
      if (items[id].rarity == "Legendary") {
        legends.push(id);
      };
    });

    console.log(`legends: ${legends}`);
    //then I random the items inside legends array to get the loot
    loot = legends[Math.floor(Math.random() * legends.length)];
    console.warn(`You looted a ${items[loot].name} | ${items[loot].rarity}`);
  };
};