闭包

闭包这个东西咋说呢,不同的程序员,不同的资料都有不同的解释,你可以把它理解成一个函数,也可以把它理解函数+执行环境。

我们这里不纠结闭包的定义,而是关注闭包的现象,应用,再结合相关面试题去攻克它,最后谈一下我对闭包的理解。

现象

之前说过,函数执行,生成执行环境,函数执行完,销毁执行环境。嗯,听上去很正常,不用的东西就销毁嘛。

但是如果函数执行完,该函数上下文还用怎么办,有用的东西肯定不敢销毁了,这个就是闭包的现象,那么引起这个现象的鄙人就把它理解成闭包!

 1 function foo () {
2 var a = 1
3 return function bar () {
4 a++
5 console.log(a)
6 }
7 }
8 var b = foo() //函数执行完,我就问你foo的上下文你敢销毁吗?
9 b() // 2
10 b() // 3

大家看到foo执行完的结果赋值给了b,也就是函数bar赋值给了b,未来我可能让b执行,也就是让bar执行,所以我需要保证让bar能访问上下文不被销毁。bar能访问的上下文实际上是foo执行的上下文。所以foo执行完以后的上下文不会被销毁,会继续存在。

我的理解是 函数向外层作用域暴露出来一个内部引用,那么就存在闭包现象。(真的没有必要纠结闭包到底是啥,是函数?内部整体?)

应用

以下代码的功能是要实现为5个input按钮循环绑定click点击事件,绑定完成后点击1、2、3、4、5五个按钮分别会alert输出0、1、2、3、4五个字符。(腾讯)

请问如下代码是否能实现?

如果不能实现那么现在的效果是什么样的?

应该做怎样的修改才能达到我们想要的效果,并说明原理?

 1 <div id="btnBox">
2 <input type="button" value="button_1" />
3 <input type="button" value="button_2" />
4 <input type="button" value="button_3" />
5 <input type="button" value="button_4" />
6 <input type="button" value="button_5" />
7 </div>
8 <script type="text/javascript">
9 var btnBox=document.getElementById('btnBox'),
10 inputs=btnBox.getElementsByTagName('input');
11 var l=inputs.length;
12 for(var i=0;i<l;i++){
13 inputs[i].onclick=function(){
14 alert(i);
15 }
16 }
17 </script>

解决思路1:没有块作用域,我就用es6的let形成块作用域

1 for(let i=0;i<l;i++){
2 inputs[i].onclick=function(){
3 alert(i);
4 }
5 }

解决思路2:每次绑定的时候i其实都是正确的,我能不能用另外一个变量将每次的i存起来呢?

1 //这样行吗?
2 for(var i=0;i<l;i++){
3 inputs[i].onclick=function(){
4 var num = i
5 alert(num);
6 }
7 }
8 //这样还是不行,因为回调函数定义的时候并不会执行,所以当var num = i 执行的时候i已经等于5了

那么我就让回调函数定义的时候里面的代码能立即执行,接收到参数0,1,2,3,4

1 for(var i=0;i<l;i++){
2 inputs[i].onclick=(function(){
3 var num = i
4 alert(num);
5 })(i)
6 }
7 //这样也有问题i传递进去了,但是里面核心代码定义也执行了,我想让它点击的时候再执行
1 for(var i=0;i<l;i++){
2 inputs[i].onclick=(function(){
3 var num = i
4 return function (e) { //注意这个时候e是啥,是点击的事件
5 console.log(num)
6 }
7 })(i)
8 } //这样就没毛病了,返回一个方法,不会立即执行,i传进去了,给了num,由于有闭包,又不会被销毁,完美

最新文章

  1. jQuery可自动播放动画焦点图插件Koala
  2. 机器指令翻译成 JavaScript —— No.2 跳转处理
  3. Sqlite 存储自定义对象
  4. SQL Server时间粒度系列----第7节日历数据表详解
  5. 接入WebSocket记录
  6. 关于ios “&lt;null&gt;”的异常处理
  7. OC中的特有语法
  8. 飞凌OK6410开发板SDIO无线8189WIFI模块驱动移植
  9. smarty基本语法
  10. asp.net Ajax Post 请求一般处理程序
  11. eclipse 常用的一些设置
  12. HTML本地存储,localstorg的应用实例
  13. IOLI-crackme0x06-0x09 writeup
  14. python的命名空间
  15. iOS9中如何注册远程通知
  16. 记录日常Linux常用软件
  17. windows重叠I/O模型
  18. 使用ycsb对hbase0.94.11 benchmark
  19. Android CollapsingToolbarLayout使用介绍
  20. 最近见到一个用react native实现的标尺动画,不知道如何实现 帖两张图(新知食App)

热门文章

  1. thinkphp 添加数据
  2. thinkphp 登录(未设置cookie+session)
  3. kkFileView对接svn服务完成文件在线预览功能
  4. Django基础四之测试环境和ORM查询
  5. 5月7日 python学习总结 MySQL数据库(一)
  6. 使用数据库连接工具DBeaver连接H2数据库
  7. php的魔术函数和魔术常量
  8. RestTemplate踩坑 之 ContentType 自动添加字符集
  9. 什么是tar 命令?
  10. MySQL 里记录货币用什么字段类型好?