今天组里小伙很纳闷的问了我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. Linq学习笔记四之linq to sql 的基本操作

    首先需要在项目中新增一个 linq  to sql 的服务 新增项,数据,LINQ TO sql 类的这个方法 第二步需要一个model类,用作映射 [Table] public class S_ZD ...

  2. 【Network】Neutron-Docker-K8S

    Neutron-Docker-K8S openstack/neutron: Neutron is a virtual network service for Openstack. Neutron和SD ...

  3. HTTP状态码

    http状态码负责表示客户端HTTP请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. 状态码类别分组如下: 1. 1XX: informational(信息性状态码)  接收的请求正 ...

  4. iOS getter setter

    getter setter 给成员变量起名字用的 setter方法 设置成员变量值 1. setter 方法一定是对象方法 不可能是类方法 2.一定没有返回值 3. 以set开头,并且set后面跟上需 ...

  5. python 旋转数组

    #!/usr/bin/env python3 #-*-encoding:utf-8-*- l = [] u = [] q = 5 xx=[[col for col in range(q)] for r ...

  6. 升级python

    一开始有这个需求,是因为用 YaH3C 替代 iNode 进行校园网认证时,一直编译错误,提示找不到 Python 的某个模块,百度了一下,此模块是在 Python2.7 以上才有的,但是系统的自带的 ...

  7. Sqlserver 2008清除数据库日志

    USE [master] GO ALTER DATABASE DBNAME SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE DBNAME SET ...

  8. Top 命令详解

    Top 命令详解 先感受一下top命令的执行结果吧!哈哈-- top - 17:32:34 up 3 days, 8:04, 5 users, load average: 0.09, 0.12, 0. ...

  9. R3.2.2安装

  10. 解决CURL 请求本地超时

    首先,这样的问题只会出现在Windows+Nginx中. php-cgi 默认使用的是9000端口,即使多个进程也并发的是9000端口 在用户访问一个php页面的时候nginx已将该进程占用,在该进程 ...