【问题标题】:Prototype objects, and object arrays原型对象和对象数组
【发布时间】:2018-01-28 12:48:44
【问题描述】:

如果这个标题没有意义,让我详细说明。

我有两个对象,一个叫 area,一个叫 enemy

每个区域都有自己的敌人,所以我为每个区域制作了敌人原型。

接下来我在每个区域原型上做了一个array.push(); 函数,所以如果用户点击一个按钮,他们将看到一个他们基本上可以探索的“区域”列表。

给我一​​个错误的主要部分是如果我尝试像alert(areas[0].enemies[0].name);这样的任何功能

如何使用按钮显示特定的敌人名称?

请不要使用 jQuery

function area(name, enemies) {
  this.name = name;
  this.enemies = enemies;
}

function enemy(name, type) {
  this.name = name;
  this.type = type;
}

var cave = new area("Cave", {
  bat: new enemy("Bat", "Flying"),
  snake: new enemy("Snake", "Ground"),
});

var forest = new area("Forest", {
  bear: new enemy("Bear", "Animal"),
  coyote: new enemy("Coyote", "Wolf"),
});

areas = [];
areas.push(cave, forest);

var thatBtn = document.getElementById('thatBtn'),
    display = document.getElementById('display');

thatBtn.addEventListener('click', function() {
  for (i = 0; i < areas.length; i++) {
    var li = document.createElement('li'),
      liBtn = document.createElement('button');
    liBtn.textContent = areas[i].name;
    li.appendChild(liBtn);
    display.appendChild(li);
    liBtn.addEventListener('click', function() {
      for (j = 0; j < areas.length; j++) {
        if (areas[j].name == event.target.textContent) {
          alert(areas[j].name);
          for (k = 0; k < Object.keys(areas[j].enemies).length; k++) {
            alert(areas[j].enemies[k].name);
          }
        }
      }
    });
  }
});

<button id="thatBtn">click here</button>
  <ul id="display">
</ul>

【问题讨论】:

  • 请采用类/可实例化函数的约定,并使用第一个大写字母作为名称。
  • 区域、洞穴、蝙蝠、敌人?
  • 仅适用于function Areafunction Enemy

标签: javascript html oop object prototype


【解决方案1】:

它给你一个错误,因为areas[0].enemies 不是一个数组——它是一个对象。

{
    bat: new enemy("Bat", "Flying"),
    snake: new enemy("Snake", "Ground"),
}

改成

for(var key in areas[j].enemies) {
    alert(areas[j].enemies[key].name);
}

【讨论】:

  • 那么我如何才能显示特定的对象名称或类型?
【解决方案2】:

enemies 是一个对象而不是数组,所以需要遍历keys 并从那里而不是从索引中获取,只是用它更新了你的 sn-p,但是代码可以更好。

function area(name, enemies){
    this.name = name;
    this.enemies = enemies;
}

function enemy(name, type){
    this.name = name;
    this.type = type;
}

var cave = new area ("Cave", {
    bat: new enemy("Bat", "Flying"),
    snake: new enemy("Snake", "Ground"),
});

var forest = new area ("Forest", {
    bear: new enemy("Bear", "Animal"),
    coyote: new enemy("Coyote", "Wolf"),
});
areas = [];
areas.push(cave, forest);

var thatBtn = document.getElementById('thatBtn'),
    display = document.getElementById('display');

thatBtn.addEventListener('click', function(){
  for(i=0; i < areas.length; i++){
    var li = document.createElement('li'),
        liBtn = document.createElement('button');
    liBtn.textContent = areas[i].name;
    li.appendChild(liBtn);
    display.appendChild(li);
    
    liBtn.addEventListener('click', function(){
      for(j=0; j < areas.length; j++){
        if (areas[j].name == event.target.textContent){
          alert(areas[j].name);
          var keys = Object.keys(areas[j].enemies);
          for(k=0; k < Object.keys(areas[j].enemies).length; k++){
            alert(areas[j].enemies[keys[k]].name);
          }
        }
      }
    });
    
  }
});
<button id="thatBtn">click here</button>
<ul id="display">
</ul>

【讨论】:

  • 太棒了!谢谢!!!而且我确信代码会更好,因为我只编写了 2-3 周的代码 :)
【解决方案3】:

将敌人添加为数组,无需在对象中使用“命名键”

function area(name, enemies){
    this.name = name;
    this.enemies = enemies;
}

function enemy(name, type){
    this.name = name;
    this.type = type;
}

var cave = new area ("Cave", [
    new enemy("Bat", "Flying"),
    new enemy("Snake", "Ground"),
]);

var forest = new area ("Forest",[ 
    new enemy("Bear", "Animal"),
    new enemy("Coyote", "Wolf"),
]);
areas = [];
areas.push(cave, forest);

var thatBtn = document.getElementById('thatBtn'),
    display = document.getElementById('display');

thatBtn.addEventListener('click', function(){
  for(i=0; i < areas.length; i++){
    var li = document.createElement('li'),
        liBtn = document.createElement('button');
    liBtn.textContent = areas[i].name;
    li.appendChild(liBtn);
    display.appendChild(li);
    
    liBtn.addEventListener('click', function(){
      for(j=0; j < areas.length; j++){
        if (areas[j].name == event.target.textContent){
          alert(areas[j].name);
          
          for(k=0; k < Object.keys(areas[j].enemies).length; k++){
            alert(areas[j].enemies[k].name);
          }
        }
      }
    });
    
  }
});
<button id="thatBtn">click here</button>
<ul id="display">
</ul>

【讨论】:

  • 太棒了,这正是我想要完成的!
【解决方案4】:

您的主要问题在这里:

for(k=0; k < Object.keys(areas[j].enemies).length; k++){
  alert(areas[j].enemies[k].name);
}

表达式Object.keys(areas[j].enemies) 返回一个对象属性数组,但随后您尝试使用k 而不是属性名称来迭代对象。

由于 Object.keys 返回一个数组,您可以使用数组方法,因此将循环更改为:

Object.keys(areas[j].enemies).forEach(function(name) {
  alert(areas[j].enemies[name]);
});

您有一个次要问题,即您没有声明循环中使用的计数器(ijk),因此它们变为代码运行时的全局变量。像这样声明它们:

for (var i=0; i < areas.length; i++) {

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多