请参阅jsfiddle:http://jsfiddle.net/LsNCa/2/
function MyFunc() {
for (var i = 0; i < 2; i++) { // i= 0, 1
var myDiv = $('<div>');
myDiv.click(function(e) {
alert(i); // both the two divs alert "2", not 0 and 1 as I expected
});
$('body').append(myDiv);
}
}
var myFunc = new MyFunc();
我想让潜水艇发出警报";0";以及";1〃;当我点击它们时,它们都会发出警报";2〃;。
当我单击div并触发事件时,处理程序如何以及在哪里找到变量i
的值?
我知道添加闭包可以实现我的目标。但为什么呢?
function MyFunc() {
for (var i = 0; i < 2; i++) { // i= 0, 1
(function(j) {
var myDiv = $('<div>');
myDiv.click(function(e) {
alert(j);
});
$('body').append(myDiv);
})(i);
}
}
var myFunc = new MyFunc();
上面的代码是如何使它正确工作的。如果没有闭包,你总是i的最后一个值。我们所做的是将i发布到闭包中,让运行时"记住"那一刻的值。
您需要一个闭包,因为所有事件处理程序函数都引用了相同的变量i
。for
循环对此进行更新,当循环完成时,变量包含2
。然后,当有人点击其中一个DIV时,它就会访问该变量。
为了解决这个问题,每个事件处理程序都需要是一个具有自己的变量i
的闭包,该变量包含创建闭包时值的快照。
我建议您阅读这篇文章
JavaScript提升声明。这意味着两个var语句和函数声明将移动到其封闭的顶部范围
正如@Barmar在上面的回答中所说,变量i
正被两个事件处理程序引用。
您应该避免在循环中声明函数。下面有一些代码可以满足您的需要。
我假设您使用的是jQuery。
function MyFunc() {
for (var i = 0; i < 2; i++) { // i= 0, 1
var myDiv = $('<div>');
$('body').append(myDiv);
}
$('div').on('click', function() {
alert($(this).index());
});
}
var myFunc = new MyFunc();
function MyFunc() {
function alertFn(val) {
return function () {
alert(val);
};
}
for (var i = 0; i < 2; i++) {
var myDiv = $('<div>');
myDiv.click(alertFn(i));
$('body').append(myDiv);
}
}
var myFunc = new MyFunc();
闭包在传递给函数时捕获"i"的值,允许alert()显示您期望的值。