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

请看以下两段代码,思考一下运行的结果是否一致呢?

代码一:

	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循环绑定监听事件索引值总是最后一个


posted @ 2017-07-24 15:20  Mr.Kay  阅读(480)  评论(0编辑  收藏  举报