很久之前就注意的问题了,今天记下来:
// data 待绑定事件数据
for(var i in data){
var metaData = data[i];
$('#meta-'+metaData.ID).click(function () {
console.log(metaData);
})
}
将一批按钮使用for循环绑定click事件,但是每次点击任何按钮,生效的效果是最后一个按钮的。经过分析,原因是:
点击按钮时候执行
// 方法体中没有metaData变量
function(){
console.log(metaData)
}
此时方法体中没有metaData变量,所以回去外部方法中寻找,此时外部for循环已经结束。并且
metaData = data[i] // 此时 i = length
因为循环结束,此时 i = data.length;所以才会导致效果和预期不一致,每次生效都的是最后一个按钮的结果。
总结,click闭包中的函数被污染,所以此时我打算采用匿名函数,避免闭包中的变量被外界访问,并且可以减少变量重复带来的困惑
// 循环绑定事件
for(var i in data){
var metaData = data[i];
// 这里的 data = metaData 当然也可用其它名称
(function(data){
$('#meta-'+data.ID).click(function () {
// 点击的时候执行点击事件,此时函数体中无data,去外部函数寻找
console.log(data);
});
})(metaData) // 将metaData 传入匿名函数
}