先看一下代码:

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. MySQL☞abs函数

    abs( )函数:求出绝对值 格式: select  abs(数值)  from 表名 如下图:

  2. 微信小程序入门学习之事件 事件对象 冒泡非冒泡事件(1)

    这关于事件的学习,可以自己复制到微信开发者工具上自己运行试试. 首先这里有两个文件.js 和.wxml 文件 首先给出.js文件下代码 // pages/news/news.js Page({ /** ...

  3. mac os x下应用endnote异常解决办法

    最近在用Office+Endnote写论文,使用拼音输入法换字时会出现重字和拼音的情况,比如我想打“桥连”,最终出现的是"qiao'lian桥lian桥连”.后来发现这个问题时由endnot ...

  4. Java学习个人备忘录之关键字static

    被static标记的东西会放在内存中被共享的,对象用到时,就会来取的. class Person { String name; //成员变量,实例变量 static String country = ...

  5. how to install pygraphviz on windows 10 with python 3.6

    Here's what worked for me: Win 7 AMD64 Install MSFT C++ compiler. Install Anaconda for Win AMD64, Py ...

  6. erlang+thrift配合开发

    I  think, thrift is a  tcp/ip based Client-Server architecture multi-languages supported RPC framewo ...

  7. c++设计模式----装饰模式

    前言 在实际开发时,你有没有碰到过这种问题:开发一个类,封装了一个对象的核心操作,而这些操作就是客户使用该类时都会去调用的操作:而有一些非核心的操作,可能会使用,也可能不会使用:现在该怎么办呢? 将这 ...

  8. python爬虫 赶集网

    #coding=utf-8import requestsfrom lxml import etreefrom sqlalchemy import create_enginefrom sqlalchem ...

  9. 用c++读取文件夹中的所有文件名

    //头文件,注意要加stdafx.h和io.h等 #include "stdafx.h" #include <io.h> #include <vector> ...

  10. An Introduction to Lock-Free Programming

    Lock-free programming is a challenge, not just because of the complexity of the task itself, but bec ...