1、最近开发中遇到一个问题,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5。
<html> ?<head> ?<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ?<title>闭包演示</title> </head> ?<body> ?<p>1</p> ?<p>2</p> ?<p>3</p> ?<p>4</p> ?<p>5</p> <script type="text/javascript">window.onload=function() { ??var ps = document.getElementsByTagName("p"); ??for( var i=0; i<ps.length; i++ ) { ????ps[i].onclick = function() { ????alert(i); ??} ??} ?} ?</script> </body> ?</html>
此时点击任意p弹出的都是5
出现原因:js事件处理器在线程空闲时间不会运行,导致最后运行的时候输出的都是i最后的值,即:5
2、解决办法:使用闭包将变量i的值保护起来。
//sava1:加一层闭包,i以函数参数形式传递给内层函数 ?for( var i=0; i<ps.length; i++ ) { ??(function(arg){ ????ps[i].onclick = function() { ?????alert(arg); ???}; ??})(i);//调用时参数 ??} ??//save2:加一层闭包,i以局部变量形式传递给内存函数 ?for( var i=0; i<ps.length; i++ ) { ??(function () { ???var temp = i;//调用时局部变量 ???ps[i].onclick = function() { ???alert(temp); ???} ??})(); ??} ?//save3:加一层闭包,返回一个函数作为响应事件(注意与3的细微区别) ?for( var i=0; i<ps.length; i++ ) { ??ps[i].onclick = function(arg) { ???return function() {//返回一个函数 ???alert(arg); ???} ??}(i); ??} ??//save4:将变量 i 保存给在每个段落对象(p)上 ??for( var i=0; i<ps.length; i++ ) { ???ps[i].i = i; ???ps[i].onclick = function() { ???alert(this.i); ???} ??} ?//save5:将变量 i 保存在匿名函数自身 ??for( var i=0; i<ps.length; i++ ) { ??(ps[i].onclick = function() { ???alert(arguments.callee.i); ??}).i = i; ??} ??} ??//save6:用Function实现,实际上每产生一个函数实例就会产生一个闭包 for( var i=0; i<ps.length; i++ ) { ???ps[i].onclick = new Function("alert(" + i + ");");//new一次就产生一个函数实例 ?} ??//save7:用Function实现,注意与6的区别 ??for( var i=0; i<ps.length; i++ ) { ????ps[i].onclick = Function(‘alert(‘+i+‘)‘); ?}
浅谈js for循环输出i为同一值的问题(闭包解决)
原文地址:http://www.cnblogs.com/wgphp/p/7805152.html