您的位置:首页 > 其它

【解决方案】闭包函数在for循环中的使用案例——for循环绑定监听事件索引值总是最后一个

2017-07-24 15:20 309 查看
请看以下两段代码,思考一下运行的结果是否一致呢?

代码一:

for (var i = 0; i < as.length; i++) {
(function () {
var j = i;
as[j].tt = tt;
as[j].onclick = function () {
this.tt.slide(j);
return false;
}
})();
}

代码二:
for (var i = 0; i < as.length; i++) {
// (function () {
// var j = i;
as[i].tt = tt;
as[i].onclick = function () {
this.tt.slide(i);
return false;
}
// })();
}

答案是不一致的,可以在循环内部绑定点击事件中输出索引值,如下:
代码一:

for (var i = 0; i < as.length; i++) {
(function () {
var j = i;
as[j].tt = tt;
as[j].onclick = function () {
console.log(j);
this.tt.slide(j);
return false;
}
})();
}

代码二:
for (var i = 0; i < as.length; i++) {
// (function () {
// var j = i;
as[i].tt = tt;
as[i].onclick = function () {
console.log(i);
this.tt.slide(i);
return false;
}
// })();
}

假设as.length = 3 ;当用户触发点击事件,
代码一运行的结果:1或2或3 (绑定成功);

代码二运行的结果:控制台输出的值始终是 3 (绑定失败)。

原因分析:js引擎的解析机制是,执行的时候将for循环中代码执行,这个时候i变成最后的值,当发生onclick事件时,会找到运算之后的i,因此绑定的事件是最后的。

所以代码一采用了闭包函数的解决方法,成功的将循环的索引值传递到点击函数内部。

此处除了使用闭包的方法外,还可以通过给对象添加一个属性,通过属性来传递索引值,如下代码所示:

for (var i = 0; i < as.length; i++) {
as[i].tt = tt;
as[i].index = i;
as[i].onclick = function () {
console.log(i);
console.log(this.index);
this.tt.slide(this.index);
return false;
}
}

此时输出结果:3,0 或 3,1 或 3,2 (绑定成功)
总之 i 的值是不变的。。。

参考资料: for循环绑定监听事件索引值总是最后一个
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: