浅谈js for循环输出i为同一值的问题


Posted in Javascript onMarch 01, 2017

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为同一值的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
一段效率很高的for循环语句使用方法
Aug 13 Javascript
javascript 页面只自动刷新一次
Jul 10 Javascript
写给想学习Javascript的朋友一点学习经验小结
Nov 23 Javascript
网站繁简切换的JS遇到页面卡死的解决方法
Mar 12 Javascript
jQuery实现点击该行即可删除HTML表格行
Oct 17 Javascript
动态的9*9乘法表效果的实现代码
May 16 Javascript
javascript实现任务栏消息提示的简单实例
May 31 Javascript
JS实现淡入淡出图片效果的方法分析
Dec 20 Javascript
vue-router路由懒加载和权限控制详解
Dec 13 Javascript
vue2.0 computed 计算list循环后累加值的实例
Mar 07 Javascript
使用Angular Cli如何创建Angular私有库详解
Jan 30 Javascript
js实现橱窗展示效果
Jan 11 Javascript
jQuery EasyUI Draggable拖动组件
Mar 01 #Javascript
Angular.js之作用域scope'@','=','&amp;'实例详解
Feb 28 #Javascript
jQuery EasyUI ProgressBar进度条组件
Feb 28 #Javascript
jQuery实现ajax无刷新分页页码控件
Feb 28 #Javascript
jQuery EasyUI Panel面板组件使用详解
Feb 28 #Javascript
AngularJS constant和value区别详解
Feb 28 #Javascript
微信小程序左右滑动切换页面详解及实例代码
Feb 28 #Javascript
You might like
PHP初学者最感迷茫的问题小结
2010/03/27 PHP
PHP常用的小程序代码段
2015/11/14 PHP
Laravel框架中Blade模板的用法示例
2017/08/30 PHP
php实现单笔转账到支付宝功能
2018/10/09 PHP
PHP面向对象程序设计之构造方法和析构方法详解
2019/06/13 PHP
国外Lightbox v2.03.3 最新版 下载
2007/10/17 Javascript
JavaScript 面向对象的 私有成员和公开成员
2010/05/13 Javascript
IE与Firefox在JavaScript上的7个不同句法分享
2011/10/30 Javascript
js修改input的type属性及浏览器兼容问题探讨与解决
2013/01/23 Javascript
jquery、js操作checkbox全选反选
2014/03/12 Javascript
jquery实现的导航固定效果
2014/04/28 Javascript
js实现遮罩层划出效果是生成div而不是显示
2014/07/29 Javascript
node.js中的fs.appendFile方法使用说明
2014/12/17 Javascript
jQuery实现仿QQ头像闪烁效果的文字闪动提示代码
2015/11/03 Javascript
js日期插件dateHelp获取本月、三个月、今年的日期
2016/03/07 Javascript
Bootstrap Metronic完全响应式管理模板之菜单栏学习笔记
2016/07/08 Javascript
原生JS实现匀速图片轮播动画
2016/10/18 Javascript
jquery pagination分页插件使用详解(后台struts2)
2017/01/22 Javascript
详解nodejs微信公众号开发——2.自动回复
2017/04/10 NodeJs
webpack dll打包重复问题优化的解决
2018/10/10 Javascript
NodeJS 文件夹拷贝以及删除功能
2019/09/03 NodeJs
Python中类的继承代码实例
2014/10/28 Python
Python实现模拟登录网易邮箱的方法示例
2018/07/05 Python
在python中实现将一张图片剪切成四份的方法
2018/12/05 Python
记录Python脚本的运行日志的方法
2019/06/05 Python
pygame实现打字游戏
2021/02/19 Python
Python随机数函数代码实例解析
2020/02/09 Python
python操作docx写入内容,并控制文本的字体颜色
2020/02/13 Python
Django+Uwsgi+Nginx如何实现生产环境部署
2020/07/31 Python
解决python3输入的坑——input()
2020/12/05 Python
收集的7个CSS3代码生成工具
2010/04/17 HTML / CSS
医科大学生的自我评价
2013/12/04 职场文书
公司领导班子对照检查存在问题整改措施
2014/10/02 职场文书
怒海潜将观后感
2015/06/11 职场文书
中小学生安全教育观后感
2015/06/17 职场文书
Spring Boot 排除某个类加载注入IOC的操作
2021/08/02 Java/Android