可能重复:
JavaScript closures and variable scope
Assign click handlers in for loop
我有这个脚本:
var MyClass = {
MyArray: new Array(0, 1, 2, 3, 4),
MyFunc1: function() {
var i = 0;
for (i = MyClass.MyArray.length - 1; i>=0; i--) {
var cen = document.getElementById("cen_" + i); // It is an img element
cen.src = "col.png";
cen.className = "cen_act";
cen.onclick = function() { MyClass.MyFunc1(i); };
} else {
cen.src = "no.png";
cen.className = "cen";
cen.onclick = null;
}
}
},
MyFunc2: function(id) {
alert(id);
}
}
我的问题是,在此行:cen.onclick = function() { MyClass.MyFunc1(i); };
发送给MyFunc2
的参数始终为 -1 。 MyFunc1
函数应创建四个图像,每个图像都带有 onclick 事件。单击每个图像时,MyFunc2函数应显示相应的 i 值。看起来 i 值并非为每个创建的事件和图像元素“保存”,而只是“指针”。
谢谢!
答案 0 :(得分:2)
您应该熟悉JavaScript closures的概念,以了解发生这种情况的原因。如果你是,那么你应该记住
的每个实例function() { MyClass.MyFunc1(i); };
函数闭包包含i
的值-1
(因为它是整个循环完成执行后该变量的最终值。)为了避免这种情况,你可以使用bind
:
cen.onclick = (function(i) { MyClass.MyFunc1(i); }).bind(null, i);
或使用具有正确i
值的显式创建的闭包。
答案 1 :(得分:1)
这是正常情况并且误解关闭,请参阅this thread,您可能会得到一些线索,解决此问题的简单方法是将包装为具有立即调用函数表达式
的循环体MyFunc1: function() {
var i = 0;
for (i = MyClass.MyArray.length - 1; i>=0; i--) {
(function(i) {
var cen = document.getElementById("cen_" + i); // An img element
cen.src = "col.png";
cen.className = "cen_act";
cen.onclick = function() { MyClass.MyFunc2(i); };
} else {
cen.src = "no.png";
cen.className = "cen";
cen.onclick = null;
}
}(i));
}
}
答案 2 :(得分:1)
您正在捕获在循环内部发生变化的变量,因此您始终可以获得i的最后一个值。
你可以通过创建一个闭包来轻松解决这个问题:
MyFunc1: function() {
var i = 0;
for (i = MyClass.MyArray.length - 1; i>=0; i--) {
(function(i) {
var cen = document.getElementById("cen_" + i); // An img element
cen.src = "col.png";
cen.className = "cen_act";
cen.onclick = function() { MyClass.MyFunc2(i); };
} else {
cen.src = "no.png";
cen.className = "cen";
cen.onclick = null;
}
})(i);
}
},