请看以下两段代码,思考一下运行的结果是否一致呢?
代码一:
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循环绑定监听事件索引值总是最后一个