繁体   English   中英

使用for-in循环迭代器设置变量的Javascript

[英]Javascript using for-in loop iterator to set a variable

我想动态创建一个按钮,该按钮将从对象中删除一个键。 但是,在这一点上,我只是使用警报来测试正确的值,该值稍后将传递给将删除键的函数。 我正在运行for-in循环,并且试图将迭代器传递给循环中调用的函数。 问题在于警报语句正在使用迭代器“ i”,并且在循环结束时,此警报的所有实例都已更改为最终值“ i”。 (我希望这是有道理的!)

    locations = {};

function Location(nickname, address) {
    this.nickname = nickname;
    this.address = address;
}

Location.prototype.showLocations = function() {
    var x=document.getElementById("demo");
    output = "<table><tr><th>Location</th><th>Address</th><th>Delete</th></tr>";
    for (i in locations) (function(i)
    {
        output+=listThis(i);           

    }) (i);
    // for (i in locations) {
    //      output+=listThis(i);
    //     }
    output+="</table>"
    x.innerHTML=output;
}

function listThis(i){
    thisLoc = locations[i].nickname;
    var thisOutput="<tr><td>"+locations[thisLoc].nickname+"</td><td>"+locations[thisLoc].address+"</td><td><input type='button' value='X' onclick='alert(locations[thisLoc].nickname)' /></td></tr>";
    return thisOutput;
}

function enterLocation() {
    var address = document.getElementById('address').value;
    var nickname = document.getElementById('nickname').value;
    locations[nickname] = new Location(nickname, address);
    locations[nickname].showLocations();
}

标记是:

<p id="demo">Table to go in here.</p>
<div id="panel">
    <input id="nickname" type="textbox" placeholder="Location Name" />
    <input id="address" type="textbox" placeholder="Sydney, NSW" />
    <input type="button" value="Enter" onclick="enterLocation()" />
</div>

请注意,我已经尝试使用在此Javascript上找到的信息-如何在带有回调的for循环中使用迭代器,但未成功。 您将看到另一个for循环被注释掉,因为我最初是在尝试。

问题在于内联onclick处理程序。

您编写onclick='alert(locations[thisLoc].nickname)' ,此处thisLoc不是对变量的直接引用。 这是一个在运行时评估的名称。

在网上thisLoc = locations[i].nickname; 您定义全局变量thisLoc ,该值将在每次迭代时覆盖。 然后,在处理onclick时,将访问具有(总是)最新值的全局变量。

有几种解决方案:

  • 不要像微型技术所说的那样使用HTML构建-使用DOM操作
  • 在构建时将值写入某些DOM属性,并在onclick处理程序中读取它:

     "<input type='button' value='X' data-location-name="' + thisLoc + '" onclick='alert(locations[this.getAttribute('data-location-name')].nickname)' />" 

正如其他人提到的那样,您需要适当地定义变量的范围(即,不要使用全局变量)。

var locations = {};

function Location(nickname, address) {
    this.nickname = nickname;
    this.address = address;
}

Location.prototype.showLocations = function() {
  var x = document.getElementById("demo");
  var output = "<table><tr><th>Location</th>" +
        "<th>Address</th><th>Delete</th></tr>";
  for (var i in locations) {
    output += listThis(i);
  }

  output += "</table>";
  x.innerHTML = output;
};

function listThis(i){
  var thisLoc = locations[i].nickname;
  var thisAddr = locations[i].address;
  var thisOutput= "<tr><td>" + thisLoc + "</td><td>" + thisAddr +
      "</td><td><input type='button' value='X' onclick='alert(\"" +
      thisLoc + "\")' /></td></tr>";
  return thisOutput;
}

function enterLocation() {
    var address = document.getElementById('address').value;
    var nickname = document.getElementById('nickname').value;
    locations[nickname] = new Location(nickname, address);
    locations[nickname].showLocations();
}

这是更新代码的摆弄

应该注意的是,此代码仍在将locations变量和所有函数添加到全局范围中,这不是推荐的做法。 解决问题所需的唯一更改是修复函数​​内部定义和使用的变量的范围。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM