浅谈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 相关文章推荐
拖动一个HTML元素
Dec 22 Javascript
javascript权威指南 学习笔记之javascript数据类型
Sep 24 Javascript
js Date概念详细介绍
Nov 22 Javascript
jquery简单倒计时实现方法
Dec 18 Javascript
关于angularJs指令的Scope(作用域)介绍
Oct 25 Javascript
Vue.js搭建移动端购物车界面
Jun 28 Javascript
JavaScript事件冒泡与事件捕获实例分析
Aug 01 Javascript
详解Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)
Apr 20 Javascript
一次让你了解全部JavaScript的作用域
Jun 24 Javascript
jquery绑定事件 bind和on的用法与区别分析
May 22 jQuery
在vue中使用Base64转码的案例
Aug 07 Javascript
如何vue使用el-table遍历循环表头和表体数据
Apr 26 Vue.js
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
php5.3 注意事项说明
2013/07/01 PHP
php一些错误处理的方法与技巧总结
2013/08/10 PHP
php冒泡排序、快速排序、快速查找、二维数组去重实例分享
2014/04/24 PHP
PHP给前端返回一个JSON对象的实例讲解
2018/05/31 PHP
Yii 实现数据加密和解密
2021/03/09 PHP
JavaScript遍历table表格中的某行某列并打印其值
2014/07/08 Javascript
javascript文本框内输入文字倒计数的方法
2015/02/24 Javascript
举例详解AngularJS中ngShow和ngHide的使用方法
2015/06/19 Javascript
jQuery图片轮播滚动切换代码分享
2020/04/20 Javascript
5个最顶级jQuery图表类库插件【jquery插件库】
2016/05/05 Javascript
基于jQuery的ajax方法封装
2016/07/14 Javascript
JS实现评价的星星功能
2017/08/20 Javascript
JS中call和apply函数用法实例分析
2018/06/20 Javascript
Three.js实现3D机房效果
2018/12/30 Javascript
js实现图片局部放大效果详解
2019/03/18 Javascript
在Python中封装GObject模块进行图形化程序编程的教程
2015/04/14 Python
利用python获取当前日期前后N天或N月日期的方法示例
2017/07/30 Python
PHP实现发送和接收JSON请求
2018/06/07 Python
Python爬虫常用小技巧之设置代理IP
2018/09/13 Python
详解python中的生成器、迭代器、闭包、装饰器
2019/08/22 Python
在Python中获取操作系统的进程信息
2019/08/27 Python
利用Python的sympy包求解一元三次方程示例
2019/11/22 Python
Django获取model中的字段名和字段的verbose_name方式
2020/05/19 Python
Python调用C语言程序方法解析
2020/07/07 Python
使用PyCharm官方中文语言包汉化PyCharm
2020/11/18 Python
肯尼迪就职演说稿
2013/12/31 职场文书
《灰椋鸟》教学反思
2014/04/27 职场文书
高考励志标语
2014/06/05 职场文书
优秀党员申报材料
2014/12/18 职场文书
英文版辞职信
2015/02/28 职场文书
2016学习雷锋精神活动倡议书
2015/04/27 职场文书
2015年高三班主任工作总结
2015/05/21 职场文书
详解GaussDB for MySQL性能优化
2021/05/18 MySQL
MySQL数据库如何给表设置约束详解
2022/03/13 MySQL
Mysql 文件配置解析介绍
2022/05/06 MySQL
JavaScript前端面试组合函数
2022/06/21 Javascript