浅谈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 相关文章推荐
基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)
Sep 02 Javascript
8款非常棒的响应式jQuery 幻灯片插件推荐
Feb 02 Javascript
jQuery-Tools-overlay 使用介绍
Jul 14 Javascript
JavaScript设计模式之单件模式介绍
Dec 28 Javascript
JS实现适合于后台使用的动画折叠菜单效果
Sep 21 Javascript
JS判断是否长按某一键的方法
Mar 02 Javascript
jQuery中的通配符选择器使用总结
May 30 Javascript
JS封装的自动创建表格的实现代码
Jun 15 Javascript
详解ECharts使用心得总结
Dec 06 Javascript
jQuery插件jqGrid动态获取列和列字段的方法
Mar 03 Javascript
jQuery的Ajax接收java返回数据方法
Aug 11 jQuery
在Angular中使用JWT认证方法示例
Sep 10 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
Windows下XDebug 手工配置与使用说明
2010/07/11 PHP
php+mysql实现的二级联动菜单效果详解
2016/05/10 PHP
php字符串比较函数用法小结(strcmp,strcasecmp,strnatcmp及strnatcasecmp)
2016/07/18 PHP
PHP封装类似thinkphp连贯操作数据库Db类与简单应用示例
2019/05/08 PHP
Thinkphp 框架扩展之应用模式实现方法分析
2020/04/27 PHP
node.js中的path.join方法使用说明
2014/12/08 Javascript
总结Javascript中的隐式类型转换
2016/08/24 Javascript
React创建组件的三种方式及其区别
2017/01/12 Javascript
Angular2学习教程之组件中的DOM操作详解
2017/05/28 Javascript
微信小程序 云开发模糊查询实现解析
2019/09/02 Javascript
微信小程序修改数组长度的问题的解决
2019/12/17 Javascript
[00:33]DOTA2上海特级锦标赛 CDEC战队宣传片
2016/03/04 DOTA
Python实现类继承实例
2014/07/04 Python
Odoo中如何生成唯一不重复的序列号详解
2018/02/10 Python
python实现简单登陆系统
2018/10/18 Python
Python小程序之在图片上加入数字的代码
2019/11/26 Python
python使用pymongo与MongoDB基本交互操作示例
2020/04/09 Python
Python openpyxl模块实现excel读写操作
2020/06/30 Python
python中append函数用法讲解
2020/12/11 Python
高性能钓鱼服装:Huk Gear
2019/02/20 全球购物
武汉英思工程科技有限公司&ndash;ORACLE面试测试题目
2012/04/30 面试题
中医专业职业生涯规划书范文
2014/01/04 职场文书
《钱学森》听课反思
2014/03/01 职场文书
石油工程专业毕业生求职信
2014/04/13 职场文书
伦敦奥运会口号
2014/06/13 职场文书
环境保护标语
2014/06/20 职场文书
2014年群众路线党员自我评议
2014/09/24 职场文书
女生抽烟检讨书
2014/10/05 职场文书
音乐教师个人工作总结
2015/02/06 职场文书
2015年小学图书室工作总结
2015/05/18 职场文书
公诉意见书范文
2015/06/05 职场文书
2016年6月份红领巾广播稿
2015/12/21 职场文书
初中体育课教学反思
2016/02/16 职场文书
在项目中使用redis做缓存的一些思路
2021/09/14 Redis
SpringBoot 整合mongoDB并自定义连接池的示例代码
2022/02/28 MongoDB
Netflix《海贼王》真人版剧集多张片场照曝光
2022/04/04 日漫