网站首页 > 技术文章 正文
更多技术分享,点击右上角红色的"关注",感谢你的支持!
闭包基本的概念
闭包并不是JavaScript特有的,在PHP、Scala、Groovy、Ruby、 Python、swift 以及Java(Java8及以上)等很多语言中,都有对闭包特性的支持。
简单来说,闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。
在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
只看这些概念,是不是有点蒙圈了,别急,且往下看。
结合代码来说明
如果一个函数a定义在另一个函数b里面,那么,这个函数a就是一个闭包。
重要的关键点,函数a能够直接读取函数b中定义的变量,这个就是闭包的特性
再来一段有意思的代码例子:
函数b这次不再直接执行a了,而是直接返回了函数a,所以func本质上是对函数a实例的引用,
而func()竟然能记住x,这就是JavaScript的闭包机制的神奇之处。
到这里,我们结合以上代码说明,闭包就是函数a和变量x。
闭包可以用来做什么
工作中,不知不觉,我们其实经常用到闭包,比如下面这个例子,一个初始化函数里面包含一个按钮点击事件:
另一个具体点的例子,一段发送验证码的Demo:
可以看到,在onclick函数里面,是可以正常操作time_wait和time_left变量的,细心的朋友可能已经发现,
代理里边已经出现两个闭包的应用了,一处是onclick,还有一处就是setInterval这个定时函数。
我们再想想,为什么要用闭包?什么场景需要呢?
JavaScript语言特性需要(setTimeout、setInterval...)
事件绑定需要(onclick...)
还有一个重要的原因,那就是OO思想,把上面发送验证码的代码改造一下来看看
这样,已经变成面向对象的编程风格了。
什么时候不该用闭包
注意了朋友,不要为了秀技巧,到处使用闭包。因为滥用闭包可能会导致脚本执行缓慢,以及消耗不必要的内存。尤其是以下两种情况时,应该尽量避免。
1.循环
页面上测试,你会发现无论你点击哪个按钮,都会弹出4,因为click函数是个闭包,页面加载后循环开始执行,当你点击按钮的时候,循环已经执行完了,此时i值为4,而闭包记得它周围的变量,所以弹出的都是4。
要解决这个问题,可以把打印的代码提炼到另一个函数里面,这样就会产生一个新的作用域:
或者用立即执行函数表达式:
2.构造器
方法应该关联于对象的原型,而不要定义到对象的构造器中。原因是这将导致每次对象实例化时,方法都会被重新定义一次。
应该这样改写,让继承的原型可以为所有实例共享:
结论
闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会徒增内存消耗!另外使用闭包也要注意变量的值是否符合你的要求,因为他就像一个静态私有变量一样。闭包通常会跟很多东西混搭起来,接触多了才能加深理解,这里只是开个头说说基础性的东西。
猜你喜欢
- 2024-10-24 Service Workers - JS API 简介(servicedescriptor)
- 2024-10-24 web性能优化的15条实用技巧(web应用性能优化思路)
- 2024-10-24 如何在 Service Worker 重新启动时重用信息
- 2024-10-24 Python在selenium里面注入JavaScript程序的方法
- 2024-10-24 requireJS 实战(requirejs define)
- 2024-10-24 面试妥了!2020 爬虫面试题目合集(爬虫面试经历)
- 2024-10-24 Nest.js 从零到壹系列(一):项目创建&路由设置&模块
- 2024-10-24 JS小知识,分享 7 个高频的工具函数,也许你用的上
- 2024-10-24 如何使用Playwright优化测试性能(play—player)
- 2024-10-24 JavaScript开发人员都应知道的异步迭代,你会了吗?
- 1507℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 502℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 484℃MySQL service启动脚本浅析(r12笔记第59天)
- 464℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 462℃启用MySQL查询缓存(mysql8.0查询缓存)
- 442℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 422℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 418℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)