先看一下代码:

01 <ul>
02     <li>1111</li>
03     <li>2222</li>
04     <li>3333</li>
05 </ul>
06 <script>
07     var a=document.getElementsByTagName('li');
08     for(var i=0,l=a.length;i<l;i++){
09         a[i].onclick=function(){
10             alert(i)
11         }
12     }
13 </script>

一个最经典的例子,上面的代码无论点击哪个结果都为最后的值,因为click事件接收的函数形成了一个闭包,闭包里的i只是对外部函数中变量i的引用,当fn执行完毕时变量i是循环得出的最后的值,闭包内的变量i也就是这个值了,所以不会依次弹出1,2,3。

至于解决的方法:

1. 为遍历的每个元素添加自定义属性用来保存当前的索引值。

1 function fn() {
2     var a = document.getElementsByTagName("li ");
3     forvar i=0; i<a.length; i++ ) {
4         a[i].i = i;
5         a[i].onclick = function() {
6             alert(this.i);
7         }
8     }
9 }

2. 将当前索引值保存到匿名函数自身。

1 function fn() {
2     var a = document.getElementsByTagName("li");
3     forvar i=0; i<a.length; i++ ) {
4         (a[i].onclick = function() {
5             alert(arguments.callee.i);
6         }).i = i;
7     }
8 }

3. 加一层闭包,将当前索引值以函数参数形式传递到内部函数。

01 function fn() {
02     var a = document.getElementsByTagName("li");
03     forvar i=0; i<a.length; i++ ) {
04         (function(arg){
05             a[i].onclick = function() {
06                 alert(arg);
07             };
08         })(i);//调用时参数
09     }
10 }

4. 加一层闭包,将当前索引值以变量形式传递到内不函数。

01 function fn() {
02     var a= document.getElementsByTagName("li");
03     forvar i=0; i<a.length; i++ ) {
04         (function () {
05             var index = i;//调用时局部变量
06             a[i].onclick = function() {
07                 alert(index);
08             }
09         })();
10     }
11 }

5. 加一层闭包,返回一个函数作为响应事件。

01 function fn() {
02     var a = document.getElementsByTagName("li");
03     forvar i=0; i<a.length; i++ ) {
04         a[i].onclick = function(arg) {
05             return function() {//返回一个函数
06                 alert(arg);
07             }
08         }(i);
09     }
10 }

6. 利用Function对象,需要注意的是Function构造函数是在脚本运行时创建函数并将参数用作新函数的参数,所以相对前几种方法执行效率较低。

1 function fn() {
2     var a = document.getElementsByTagName("li");
3     forvar i=0; i<a.length; i++ ) {
4         a[i].onclick = Function('alert('+i+')')
5     }
6 }

7. 利用Function对象实例来产生闭包。

1 function fn() {
2     var a= document.getElementsByTagName("li");
3     forvar i=0; i"a.length; i++ ) {
4         a[i].onclick = new Function('alert(' +i+' )' );//new一次就产生一个函数实例
5     }
6 }

最新文章

  1. Android自定义控件之自定义组合控件
  2. 【C++】类和对象(构造与析构)
  3. JSPatch常见问题解答
  4. poj 3278:Catch That Cow(简单一维广搜)
  5. [BZOJ 1483][HNOI 2009]梦幻补丁(有序表启发式合并)
  6. word-break:break-all和word-wrap:break-word的区别
  7. android studio添加三方jar包
  8. 插入数据前设置字符编码为utf8
  9. springboot~mogodb多条件拼接
  10. pytho命名规范
  11. Springboot(一)概念
  12. 023 SpringMVC拦截器
  13. dbcp、c3p0、jdbc常用连接配置
  14. Zabbix二次开发_01基础
  15. Hadoop HBase概念学习系列之HBase里的宽表设计概念(表设计)(二十七)
  16. BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆
  17. web文件上传组件比较jQuery File Upload和Fine Uploader
  18. Android Studio怎样查看资源或者函数在哪些类中被引用
  19. Kubuntu中thunderbird最小化到任务栏
  20. 1-求组合数(c(n, m))的几种方法

热门文章

  1. JMeter 录制APP脚本
  2. Web自动化selenium技术快速实现爬虫
  3. ubuntu下Nodic开发环境搭建
  4. Ext JS 6学习文档-第3章-基础组件
  5. js经典试题之数组与函数
  6. Uncaught Error: Syntax error, unrecognized expression: |117的js错误
  7. 总结Canvas和SVG的区别
  8. FromHandle临时对象一探究竟
  9. 访问方式由http改为https curl:(51)
  10. Jrebel 工具学习