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 相关文章推荐
JS基础之undefined与null的区别分析
Aug 08 Javascript
jQuery 隐藏和显示 input 默认值示例
Jun 03 Javascript
js数组与字符串的相互转换方法
Jul 09 Javascript
javascript继承机制实例详解
Nov 20 Javascript
折叠菜单及选择器的运用
Feb 03 Javascript
判断滚动条滑到底部触发事件(实例讲解)
Nov 15 Javascript
ionic2中使用自动生成器的方法
Mar 04 Javascript
基于Vue的延迟加载插件vue-view-lazy
May 21 Javascript
跨域解决之JSONP和CORS的详细介绍
Nov 21 Javascript
node学习笔记之读写文件与开启第一个web服务器操作示例
May 29 Javascript
浅谈webpack构建工具配置和常用插件总结
May 11 Javascript
解决qrcode.js生成二维码时必须定义一个空div的问题
Jul 09 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
PHP 文件扩展名 获取函数
2009/06/03 PHP
php strrpos()与strripos()函数
2013/08/31 PHP
javascript 动态添加表格行
2006/06/22 Javascript
js修改input的type属性及浏览器兼容问题探讨与解决
2013/01/23 Javascript
一个例子轻松学会Vue.js
2017/01/02 Javascript
vue-dialog的弹出层组件
2020/05/25 Javascript
ES6中参数的默认值语法介绍
2017/05/03 Javascript
浅谈js基础数据类型和引用类型,深浅拷贝问题,以及内存分配问题
2017/09/02 Javascript
详解Axios统一错误处理与后置
2018/09/26 Javascript
Vue 配合eiement动态路由,权限验证的方法
2018/09/26 Javascript
微信小程序使用wxParse解析html的方法示例
2019/01/17 Javascript
手把手教您实现react异步加载高阶组件
2020/04/07 Javascript
深入浅析vue全局环境变量和模式
2020/04/28 Javascript
[01:04:08]完美世界DOTA2联赛PWL S3 INK ICE vs GXR 第一场 12.16
2020/12/18 DOTA
Pandas实现数据类型转换的一些小技巧汇总
2018/05/07 Python
详解Python下ftp上传文件linux服务器
2018/06/21 Python
Django管理员账号和密码忘记的完美解决方法
2018/12/06 Python
对Python中创建进程的两种方式以及进程池详解
2019/01/14 Python
Python/Django后端使用PIL Image生成头像缩略图
2019/04/30 Python
Python PyInstaller库基本使用方法分析
2019/12/12 Python
python实现udp传输图片功能
2020/03/20 Python
Python实现http接口自动化测试的示例代码
2020/10/09 Python
John Hardy官方网站:手工设计首饰的奢侈品牌
2017/07/05 全球购物
求职信内容考虑哪几点
2013/10/05 职场文书
求职简历自荐信范文
2013/10/21 职场文书
财务助理岗位职责
2013/11/10 职场文书
村官工作鉴定评语
2014/01/27 职场文书
《三袋麦子》教学反思
2014/03/02 职场文书
党的群众路线教育实践活动公开承诺书
2014/03/28 职场文书
2014最新预备党员思想汇报范文:中国梦,我的梦
2014/10/25 职场文书
感恩主题班会教案
2015/08/12 职场文书
《自己去吧》教学反思
2016/02/16 职场文书
如何书写先进事迹材料?
2019/07/02 职场文书
导游词之吉林吉塔
2019/11/11 职场文书
nginx location优先级的深入讲解
2021/03/31 Servers
pytorch 预训练模型读取修改相关参数的填坑问题
2021/06/05 Python