JS闭包经典实例详解

 更新时间:2018年12月20日 11:01:27   作者:huansky  
这篇文章主要介绍了JS闭包,结合一个经典实例较为详细的分析了javascript闭包的原理及使用方法,需要的朋友可以参考下

本文实例讲述了JS闭包。分享给大家供大家参考,具体如下:

之前花了很多时间看书上对闭包的介绍,也看了很多人的写的关于闭包的博客,然后我就以为自己懂了。

结果,下午在一个QQ群里,有人问了这道经典的闭包问题,如下图:

我告诉他去看书上的闭包介绍。告诉他之后,我想我自己要不也写一下,反正花不了多少时间,结果花了好久怎么写也不对..............

后来看了看书上的,然后自己总结了下,觉得这次应该懂了。下次还不理解我就可以去跳楼了............

-----------------------------------分割线-----------------------------------分割线--------------------------

首先我们来了解几个概念:

立即执行函数:形如 (function(){})();的一类函数;

闭包:闭包是指有权访问另一函数作用域中的变量的函数。

作用域链:当代码执行的时候,会创建变量对象的一个作用域链....(具体百度)

我们再来看这个问题,我重新写了一个,源码如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>闭包经典例子详解——huansky</title>
</head>
<body>
  <div id="ttt">
    <p >000000000000000000</p>
      <br>
    <p >111111111111111111</p>
    <br>
    <p >222222222222222222</p>
  </div>
</body>
<script>
var dom=document.getElementsByTagName("p");
for(var i=0;i<dom.length;i++){
    dom[i].onclick=function(){
      console.log(i);//3
    };
}
</script>
</html>

首先,代码中的匿名函数没有变量 i,所以它必须向上查找,在全局环境中找到了 i。

for循环运行后,全局变量中的 i 变成了3。此时当你点击文字的时候,会调用其绑定的函数,而该函数运行的时候,发现自己没有 i,就会取得全局环境中的 i。

所以,最后的结果是,不管你点击那段文字,最后结果都是3。

PS:感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具http://tools.jb51.net/code/HtmlJsRun测试上述代码,看看运行效果。

那怎么办呢?你可以用立即执行函数,看代码:

for(var i=0;i<dom.length;i++){
    dom[i].onclick=function(i){
      return function( ){
      console.log(i);
      };
    }(i);
}

我们把参数 i 作为传给立即执行函数,这样,i 的值就传给了立即执行函数的局部变量 i 了。立即执行函数会直接执行,但是其活动不会销毁,因为里面有个匿名函数。执行后局部变量 i 与全局变量 i 联系就切断了,也就是执行的时候,传进去的变量 i 是多少,立即执行函数的局部变量 i  就是多少,并且该局部变量 i 仍然没有消失,因为匿名函数的存在。

这时候,return中的匿名函数的作用域链中会有两个变量 i。当点击文本的时候,它向上搜索 i 的时候,它找到立即执行函数的局部变量 i ,就停止向上查找了,因此最后的结果就不会是全局变量 i 的值3了。

有一个方法可以检验你们有没有真的理解上面所说的,看上面的变体,代码:

for(var i=0;i<dom.length;i++){
    dom[i].onclick=function(t){
      return function( ){
      console.log(t);//1
      console.log(i);//3
      };
    }(i);
}

其实return中的匿名函数中的 t 就是立即执行函数的局部变量 i,而 i 就是 指全局变量 i,因为立即执行函数中没有变量i,只能继续向上搜索,然后就找到全局变量的 i 了。

如果看到这里,你还没有理解,有两个原因:一个原因是我表达的不够好,另一个原因是你没有完全理解前面提到的这些概念,还要继续看书。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结

希望本文所述对大家JavaScript程序设计有所帮助。

相关文章

  • 原生JS实现目录滚动特效

    原生JS实现目录滚动特效

    这篇文章主要为大家详细介绍了原生JS实现目录滚动特效,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • JS实现数组过滤从简单到多条件筛选

    JS实现数组过滤从简单到多条件筛选

    一般情况下的单条件筛选,数组的filter方法就能够满足需求,本文讨论的重点是多条件下的复合筛选,并列出了几个相关知识点,感兴趣的可以了解一下
    2021-07-07
  • 微信小程序实现人脸识别登陆的示例代码

    微信小程序实现人脸识别登陆的示例代码

    这篇文章主要介绍了微信小程序实现人脸识别登陆的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 基于javascript的无缝滚动动画1

    基于javascript的无缝滚动动画1

    这篇文章主要介绍了基于javascript的无缝滚动动画实现,文章通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • js中如何完美的解析数据

    js中如何完美的解析数据

    这篇文章给大家分享了JS中完美解析数据的方法和技巧,对此有兴趣的朋友可以参考学习下。
    2018-03-03
  • JavaScript制作的可折叠弹出式菜单示例

    JavaScript制作的可折叠弹出式菜单示例

    弹出式菜单想必大家在浏览网页时都有见过吧,本文要为大家介绍的是可折叠的弹出式菜单,你若感兴趣可以参考下
    2014-04-04
  • js 获取扫码枪输入数据的方法

    js 获取扫码枪输入数据的方法

    这篇文章主要介绍了js 获取扫码枪输入数据的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • 微信小程序上传图片并等比列压缩到指定大小的实例代码

    微信小程序上传图片并等比列压缩到指定大小的实例代码

    这篇文章主要介绍了微信小程序 上传图片并等比列压缩到指定大小,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-10-10
  • JavaScript实现正则去除a标签并保留内容的方法【测试可用】

    JavaScript实现正则去除a标签并保留内容的方法【测试可用】

    这篇文章主要介绍了JavaScript实现正则去除a标签并保留内容的方法,结合实例形式详细分析了javascript针对a标签及span标签的正则匹配相关操作技巧,需要的朋友可以参考下
    2018-07-07
  • javascript显示动态时间的方法汇总

    javascript显示动态时间的方法汇总

    本文给大家汇总介绍了3种javascript实现动态显示时间的方法及详细示例,有需要的小伙伴可以参考下
    2018-07-07

最新评论