今天组里小伙很纳闷的问了我js绑事件带出的一个小问题,随便聊聊闭包那点事,背景如下:

当点击Button的时候给li绑定事件,事件的大概内容是获取li位置的index再做点事,据他描述代码看上去也没错,就是index一直是最后一个值

UI代码:

<button id="btnAttach"></button>

<ul id="ulTarget">
<li>我是第一个</li>
<li>我是第二个</li>
<li>我是第三个</li>
<li>我是第四个</li>
</ul>

js代码:

$("#btnAttack").bind("click",
function(){
var a = $("#J_memberslide").find("li");
for(var i=0;a && i<a.length;i++){
$(a[i]).bind("click",
function(){
alert(i);
});
}
    a=null;
});

当然demo代码是精简过的示意代码,大概意思是点击按钮后,让ul下的li绑定click事件,click事件的内容是输出当前li的positioin的index值。

代码结果:点击任意一个li,输出都是3

代码分析

按钮事件内,通过循环的方式给每个li对象绑定了事件,事件的主体为一匿名函数,这里的匿名函数就成了一个闭包,在匿名函数内部引用了外部的变量i, 当函数执行时输出i的值

问题
为什么当点击触发匿名事件时,i的值一直是3

答案

当按钮事件绑定时,闭包引用的外部变量i的值并未被闭包访问,仅引用了变量i,即当循环绑定结束后i的值为3,而不绑定时取到i的值并保存,这是关键。

当li被点击时匿名函数才去访问变量i的值,即3,所以所有li点击时都输出的3

总结

闭包是JS经典特色之一,当它在你身边不必惊慌,也不要忽略

js闭包-在你身边却不知的更多相关文章

  1. js闭包的作用域以及闭包案列的介绍:

    转载▼ 标签: it   js闭包的作用域以及闭包案列的介绍:   首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几 ...

  2. 大部分人都会做错的经典JS闭包面试题

    由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...

  3. Js闭包常见三种用法

        Js闭包特性源于内部函数可以将外部函数的活动对象保存在自己的作用域链上,所以使内部函数的可以将外部函数的活动对象占为己有,可以在外部函数销毁时依然存有外部函数内的活动对象内容,这样做的好处是可 ...

  4. js闭包之初步理解( JavaScript closure)

    闭包一直是js中一个比较难于理解的东西,而平时用途又非常多,因此不得不对闭包进行必要的理解,现在来说说我对js闭包的理解. 要理解闭包,肯定是要先了解js的一个重要特性, 回想一下,那就是函数作用域, ...

  5. (原创)JS闭包看代码理解

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

  6. js闭包理解

    js闭包的作用是使函数外可以访问函数内部的变量,是通过 在函数内部 定义 访问函数内变量 的函数实现的,内部的一个函数产生一个闭包 function a() { var i=0; return fun ...

  7. js闭包理解实例小结

    Js闭包 闭包前要了解的知识  1. 函数作用域 (1).Js语言特殊之处在于函数内部可以直接读取全局变量 <script type="text/javascript"> ...

  8. Js闭包的用途

    本来想总结一点JavaScript中的闭包的一些用法,在查资料的时候发现了一篇很好的文章,就转过来收藏了,下面附上传送门: js闭包的用途 ---------sunlylorn 我们来看看闭包的用途. ...

  9. js闭包和ie内存泄露原理

    也议 js闭包和ie内存泄露原理 可以, 但小心使用. 闭包也许是 JS 中最有用的特性了. 有一份比较好的介绍闭包原理的文档. 有一点需要牢记, 闭包保留了一个指向它封闭作用域的指针, 所以, 在给 ...

随机推荐

  1. Windows 10(64位)配置Caffe运行环境的基本流程

    最新博客地址已搬家到: http://blog.csdn.net/zzlyw/article/details/53215148

  2. PHP 查看安装信息

    1.运行PHP脚本,查看phpinfo函数的输出. 2.在系统环境变量Path中配好php.exe可执行文件的路径,命令管理器CMD中,执行`php.exe -i`查看. 3.在phpinfo()的输 ...

  3. SQLite.Net-PCLUSING SQLITE IN WINDOWS 10 UNIVERSAL APPS

    USING SQLITE IN WINDOWS 10 UNIVERSAL APPS 1.下载SQLite VSIX package并安装 http://sqlite.org/download.html ...

  4. $_session (应用)

    登录: 封装类(用于连接数据库)代码中创建一个对象最好可以重复使用 <?php class DBDA { public $host="localhost"; public $ ...

  5. 用 javassist 来修改 class 文件

    import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; public class Test { ...

  6. CentOS下yum安装LAMP

    1. 用yum安装Apache,Mysql,PHP. 1.1安装Apache yum install httpd httpd-devel 安装完成后,用/etc/init.d/httpd start  ...

  7. 【转】代码中特殊的注释技术——TODO、FIXME和XXX的用处

    (转自:http://blog.csdn.net/reille/article/details/7161942) 作者:reille 本博客网址:http://blog.csdn.net/reille ...

  8. Swift - UIView,UItableView,Cell设置边框方法

    // 设置边框的宽度 cell.layer.borderWidth = 1 // 设置边框的颜色 cell.layer.borderColor = UIColor.blackColor().CGCol ...

  9. plsql配置远程连接数据库

    1.先安装plsql.地址:http://pan.baidu.com/s/1hqGbATI 2.  解压缩 instantclient_11_2(这个客户端可以在网上找精简版的),找到以下路径  \i ...

  10. Js实现string.format

    经常需要动态拼接html字符串,想到用类似于.net的string.format函数比较好,于是找了下,stackoverflow的代码: if (!String.prototype.format) ...