JS闭包经典实例详解


Posted in Javascript onDecember 20, 2018

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

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

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

JS闭包经典实例详解

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

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

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

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

立即执行函数:形如 (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.3water.com/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 css在IE和Firefox中区别分析
Feb 18 Javascript
jquery URL参数判断,确定菜单样式
May 31 Javascript
一个可绑定数据源的jQuery数据表格插件
Jul 17 Javascript
jQuery实现的多选框多级联动插件
May 02 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
Mar 05 Javascript
js模拟淘宝网的多级选择菜单实现方法
Aug 18 Javascript
jquery对象访问是什么及使用方法介绍
May 03 Javascript
全面解析Bootstrap中Carousel轮播的使用方法
Jun 13 Javascript
JS生成一维码(条形码)功能示例
Jan 19 Javascript
学习使用jQuery表单验证插件和日历插件
Feb 13 Javascript
Angular企业级开发——MVC之控制器详解
Feb 20 Javascript
javascript连接mysql与php通过odbc连接任意数据库的实例
Dec 27 Javascript
JS闭包原理与应用经典示例
Dec 20 #Javascript
Mint UI组件库CheckList使用及踩坑总结
Dec 20 #Javascript
从零开始在NPM上发布一个Vue组件的方法步骤
Dec 20 #Javascript
微信小程序实现swiper切换卡内嵌滚动条不显示的方法示例
Dec 20 #Javascript
微信小程序实现的点击按钮 弹出底部上拉菜单功能示例
Dec 20 #Javascript
vue+Vue Router多级侧导航切换路由(页面)的实现代码
Dec 20 #Javascript
微信小程序module.exports模块化操作实例浅析
Dec 20 #Javascript
You might like
用IE远程创建Mysql数据库的简易程序
2006/10/09 PHP
用windows下编译过的eAccelerator for PHP 5.1.6实现php加速的使用方法
2007/09/30 PHP
PHP利用str_replace防注入的方法
2013/11/10 PHP
php解决约瑟夫环示例
2014/04/09 PHP
简单说说PHP优化那些事(经验分享)
2014/11/27 PHP
PHP实现通用alert函数的方法
2015/03/11 PHP
php实现在服务器上创建目录的方法
2015/03/16 PHP
javascript学习网址备忘
2007/05/29 Javascript
jQuery中prevAll()方法用法实例
2015/01/08 Javascript
详解AngularJS中的依赖注入机制
2015/06/17 Javascript
jQuery实现百叶窗焦点图动画效果代码分享(附源码下载)
2016/03/14 Javascript
DWR中各种java方法的调用
2016/05/04 Javascript
浅谈原生JS实现jQuery的animate()动画示例
2017/03/08 Javascript
微信小程序scroll-view横向滑动嵌套for循环的示例代码
2018/09/20 Javascript
在vue-cli的组件模板里使用font-awesome的两种方法
2018/09/28 Javascript
记一次vue-webpack项目优化实践详解
2019/02/17 Javascript
js tab栏切换代码实例解析
2019/09/03 Javascript
微信小程序pinker组件使用实现自动相减日期
2020/05/07 Javascript
基于better-scroll 实现歌词联动功能的代码
2020/05/07 Javascript
vue+elementUI 实现内容区域高度自适应的示例
2020/09/26 Javascript
Python实现网站文件的全备份和差异备份
2014/11/30 Python
Python下线程之间的共享和释放示例
2015/05/04 Python
Python实现的摇骰子猜大小功能小游戏示例
2017/12/18 Python
Python实现的将文件每一列写入列表功能示例【测试可用】
2018/03/19 Python
浅谈解除装饰器作用(python3新增)
2018/10/15 Python
python树的同构学习笔记
2019/09/14 Python
python使用opencv在Windows下调用摄像头实现解析
2019/11/26 Python
python访问hdfs的操作
2020/06/06 Python
利用HTML5绘制点线面组成的3D图形的示例
2015/05/12 HTML / CSS
比较基础的php面试题及答案-编程题
2012/10/14 面试题
女子职高个人自荐书
2014/02/01 职场文书
办护照工作证明
2014/10/01 职场文书
缓刑期间思想汇报范文
2014/10/10 职场文书
2015最新婚礼主持词
2015/06/30 职场文书
python - asyncio异步编程
2021/04/06 Python
MySQL EXPLAIN输出列的详细解释
2021/05/12 MySQL