如何评估功能声明中的变量?

时间:2012-10-22 18:41:35

标签: javascript loops declaration

我正在编写一个简单的JavaScript表单,它是一个设备列表,每个设备旁边都有一个按钮,按钮应该将您带到文本字段,您可以在其中编辑有关设备的信息。相反,所有按钮都会将您带到列表中最后一个设备的信息。以下是我正在创建列表的片段:

for(var i in portal.clients){
  var row = document.createElement('tr');
  var cell2 = document.createElement('td');
  var button = document.createElement('button')
  var title = document.createTextNode("Edit Config")
  button.appendChild(title)
  button.onclick = function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}
  cell2.appendChild(button)
  row.appendChild(button)

  var cell1 = document.createElement('td');
  var client = document.createTextNode(portal.clients[i].info.description.name)
  cell1.appendChild(client)
  row.appendChild(cell1)
  table.appendChild(row);
}

我认为问题在于,当单击按钮时,i函数声明中的onClick将被评估,而不是像我指的那样声明函数。有没有办法可以在声明函数时强制求变量?或者我是否应该使用其他方法将客户端索引传递给函数?

3 个答案:

答案 0 :(得分:4)

任何时候你想在回调中使用你的迭代变量i(即在你的循环完成之后才会被评估的东西)你需要在新范围内捕获变量。

for(var i in portal.clients){
    (function(i){
        // do something later with i
    })(i);
}

关于JavaScript中的作用域,这里有很多关于SO的讨论。我强烈建议您阅读它,因为以任何重要方式理解JavaScript都是必不可少的。

答案 1 :(得分:1)

您需要创建一个新范围,其中i的副本适用于每次迭代。在您提供的代码中,您可以通过编写一个立即运行的函数来创建一个新的作用域,并返回您希望与附加的新作用域中的变量一起使用的实际函数:

for(var i in portal.clients) {
  var row = document.createElement('tr');
  var cell2 = document.createElement('td');
  var button = document.createElement('button')
  var title = document.createTextNode("Edit Config")
  button.appendChild(title)
  button.onclick = (function(i){return function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}; })(i);
  cell2.appendChild(button)
  row.appendChild(button)

  var cell1 = document.createElement('td');
  var client = document.createTextNode(portal.clients[i].info.description.name)
  cell1.appendChild(client)
  row.appendChild(cell1)
  table.appendChild(row);
}

答案 2 :(得分:0)

您可以通过将循环置于自执行功能中来解决它。未经测试的例子:

for(var i in portal.clients){
  (function (i) {
    var row = document.createElement('tr');
    var cell2 = document.createElement('td');
    var button = document.createElement('button')
    var title = document.createTextNode("Edit Config")
    button.appendChild(title)
    button.onclick = function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}
    cell2.appendChild(button)
    row.appendChild(button)

    var cell1 = document.createElement('td');
    var client = document.createTextNode(portal.clients[i].info.description.name)
    cell1.appendChild(client)
    row.appendChild(cell1)
    table.appendChild(row);
  })(i);
}