Javascript循环中的事件处理程序 – 需要closures?

我正在处理一些我从其他人手中接过的html和Javascript代码。 该页面每十秒钟重新载入一个数据表(通过asynchronous请求),然后使用一些DOM代码重新构build表。 有问题的代码看起来像这样:

var blah = xmlres.getElementsByTagName('blah'); for(var i = 0; i < blah.length; i++) { var td = document.createElement('td'); var select = document.createElement('select'); select.setAttribute("...", "..."); select.onchange = function() { onStatusChanged(select, callid, anotherid); }; td.appendChild(select); } 

但是,如果为<select>元素触发onchange事件,则表中的每个<select>都会将相同的值传递给onStatusChanged()方法(我已经validation了在循环的每次迭代中, callidanotherid正在被赋予新的,不同的值)。

我怀疑这是发生,因为我设置事件处理程序的性质,使用select.onchange = function()语法。 如果我理解这是如何工作的,那么这个语法将onchange事件的闭包设置为一个引用这两个引用的函数,这个引用最终具有在循环的最后一次迭代中设置的最终值。 当事件触发时, callidanotherid引用的值是最后一次迭代中设置的值,而不是单个迭代中设置的值。

有没有办法,我可以复制我传递给onStatusChanged()参数的值?

我已经改变了标题,以更好地反映问题和接受的答案。

你确实需要在这里实施一个closures。 这应该工作(让我知道 – 我没有testing)

 var blah = xmlres.getElementsByTagName('blah'); for(var i = 0; i < blah.length; i++) { var td = document.createElement('td'); var select = document.createElement('select'); select.setAttribute("...", "..."); select.onchange = function(s,c,a) { return function() { onStatusChanged(s,c,a); } }(select, callid, anotherid); td.appendChild(select); }