先看一下代码:

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     for( var 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     for( var 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     for( var 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     for( var 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     for( var 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     for( var 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     for( var i=0; i"a.length; i++ ) {
4         a[i].onclick = new Function('alert(' +i+' )' );//new一次就产生一个函数实例
5     }
6 }

JavaScript闭包的特性的更多相关文章

  1. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  2. javascript闭包函数

    JavaScript中的匿名函数及函数的闭包   1.匿名函数 2.闭包 3.举例 4.注意 1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没 ...

  3. Javascript闭包和C#匿名函数对比分析

    C#中引入匿名函数,多少都是受到Javascript的闭包语法和面向函数编程语言的影响.人们发现,在表达式中直接编写函数代码是一种普遍存在的需求,这种语法将比那种必须在某个特定地方定义函数的方式灵活和 ...

  4. 理解JAVASCRIPT 闭包

    最近去面试了一家企业,结果非常灰心丧气,于是周末给自己定了一个目标 学好一门,学精通一门.不求多,只求懂. 最近看到一个概念“闭包”. 什么是闭包呢? 简单一点就是:看得到多和看得到少的区别. 上面这 ...

  5. 转:深入理解JavaScript闭包概念

    闭包向来给包括JavaScript程序员在内的程序员以神秘,高深的感觉,事实上,闭包的概念在函数式编程语言中算不上是难以理解的知识.如果对作用域,函数为独立的对象这样的基本概念理解较好的话,理解闭包的 ...

  6. JavaScript 闭包整合

    初遇闭包感觉很困惑,上网查看了些许介绍,有很多没看懂,就想先对能懂的东西整整 首先觉得要了解闭包,要先对一.JavaScript的变量作用域和作用域链有基本了解 1.变量的作用域分为:全局变量和局部变 ...

  7. javascript进阶——面向对象特性

    面向对象的javascript是这门语言被设计出来时就考虑的问题,熟悉OOP编程的概念后,学习不同的语言都会发现不同语言的实现是不同的,javascript的面向对象特性与其他具有面向对象特性的语言的 ...

  8. JavaScript闭包的一些理解

    原文:JavaScript闭包的一些理解 简单一点的说:闭包就是能够读取其他函数内部变量的函数.那如何实现读取其它函数内部变量呢,大家都知道在JavaScript中内部函数可以访问其父函数中的变量,那 ...

  9. javascript闭包1

    javascript闭包 在学习javascript闭包之前,需要先了解一下"作用域链". 每一段javascript代码都有一个与之关联的作用域链(scope chain),这个 ...

随机推荐

  1. [SHELL]shell中的数学运算

    一,expr  太麻烦,看的脑壳疼 二,使用方括号 !!!! bash shell用这种方法只支持整数运算,z shell倒是支持浮点型运算 var_1= var_2= var_3= my_var_1 ...

  2. 在页面使用echarts的地图(解决地图不完整)

    测试环境:IDEA+Tomcat7 谷歌浏览器 创建好web工程,编写jsp页面,在自己编写的JSP页面上导包 现在echarts停止了在其网站上下载地图脚本,直接通过src引用网站上的china.j ...

  3. 聊聊、dubbo 找不到 dubbo.xsd 报错

    平常在用 Dubbo 的时候,创建 xml 会提示 http://code.alibabatech.com/schema/dubbo/dubbo.xsd 找不到. 大家可以去 https://gith ...

  4. oraclize预言机资料

    oraclize预言机资料 智能合约如何可信的与外部世界交互: https://blog.csdn.net/sportshark/article/details/77477842 国外一篇讲得很详细的 ...

  5. 四、oracle 用户管理二

    一.使用profile管理用户口令概述:profile是口令限制,资源限制的命令集合,当建立数据库时,oracle会自动建立名称为default的profile.当建立用户没有指定profile选项时 ...

  6. 小程序的picker的range 是一个 Object Array (对象数组)

    小程序的picker的range 是一个 Object Array (对象数组) 数据: array: [{'id':1,'name':'Android'},{'id':2,'name':'IOS'} ...

  7. JavaScript初探系列之数组的基本操作

    在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活.强大,不像是Java等强类型高级语言数组只 ...

  8. java—连连看GUI

    1.连连看棋盘图形化 package Link; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; impo ...

  9. [经典贪心算法]Prim算法

    最小生成树的Prim算法也是贪心算法的一大经典应用.Prim算法的特点是时刻维护一棵树,算法不断加边,加的过程始终是一棵树. Prim算法过程: 一条边一条边地加, 维护一棵树. 初始 E = {}空 ...

  10. javaweb引用jar类库的问题

    JAVAWEB中,需要引用的jar类库必须放在/WebContent/WEB-INF/lib文件夹中.不然就会各种报错.