先看一下代码:

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 }

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. selenium元素定位(三)

    使用selenium就不可避免的要提到界面元素定位,通过元素定位来实现一系列的逻辑操作. selenium提供了8中元素定位的方式: id.name.class name.tag name.link ...

  2. Linux文件系统简介和软链接和硬链接的区别

    Linux有着极其丰富的文件系统,大体可分为如下几类: 网络文件系统:如nfs.cifs等: 磁盘文件系统:如ext3.ext4等: 特殊文件系统:如prco.sysfs.ramfs.tmpfs等: ...

  3. java并发总览

  4. 幸运的袋子(深度优先遍历(Depth First Search,DFS))

    题目描述 一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的).如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积. 例如:如果袋子里面的球的号码是{1, 1, 2 ...

  5. Python3 小工具-ARP扫描

    from scapy.all import * import optparse import threading import os def scan(ipt): pkt=Ether(dst='ff: ...

  6. 第十六次ScrumMeeting会议

    第十六次Scrum Meeting 时间:2017/12/6 地点:线上+SPR咖啡馆 人员:蔡帜 王子铭 游心 解小锐 王辰昱 李金奇 杨森 陈鑫 照片: 目前工作进展 名字 今日 明天的工作 遇到 ...

  7. UML设计(团队作业)

    UML设计 一.团队信息 1.队名 读完文章再睡觉 2.团队成员的学号与姓名 学号 姓名 211606381 吴伟华(队长) 211606369 蔺皓雯 211606340 杨池宇 211606372 ...

  8. UML建模语言入门-视图,事物,关系,通用机制

    . 作者 :万境绝尘  转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/18964835 . 一. UML视图 1. Ration ...

  9. java — 设计模式

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 一.设计模式的分类 ...

  10. ZooKeeper server &&client

    写了一个关于zookeepeer应用的简单demo 服务端定时的向zookeeper集群注册,客户端监听zookeeper服务节点变化,一旦变化,立刻响应,更新服务端列表 服务端代码: #includ ...