1、JS中的闭包
1、如何产生闭包?
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量时,就会产生闭包
闭包存在于嵌套的内部函数中
产生闭包的条件
函数嵌套+
内部函数引用了外部函数的数据(变量或者函数)+
执行外部函数(执行内部函数定义就会产生闭包,甚至不用调用内部函数)
2、常见的闭包
2.1、将函数作为另一个函数的返回值
2.2、将函数作为实参传递给另一个函数调用
<script type="text/javascript"> // 1. 将函数作为另一个函数的返回值 function fn1() { var a = 2 function fn2() { a++ console.log(a) } return fn2//将内部函数作为返回值返回(函数也是数据,是数据就能返回) };
var f = fn1() f() // 3,执行这个f()实际上是执行了f1中的内置函数 f() // 4,闭包产生几次,就看外部函数调用几次,这里的两个f()实际上都是调用内部函数fn2() // 2. 将函数作为实参传递给另一个函数调用 function showMsgDelay(msg, time) { setTimeout(function () { console.log(msg) //闭包里面只有msg,time不在内部函数中 alert(msg) }, time) } showMsgDelay('hello', 1000) </script>
3、闭包的作用
3.1 使函数内部的变量在函数执行完后,仍然存在于内存中,延长局部变量的生命周期
3.2 让函数外部可以操作内部的数据(变量、函数)
一些问题:
--函数执行完后,函数内部声明的局部变量是否存在? 一般不存在,存在于闭包中的变量才“可能”存在(若没有引用的,亦不存在)
--函数外部可以直接访问到内部的局部变量吗? 不能,但是可以通过闭包来操作
4、闭包的生命周期
产生:在嵌套内部函数定义执行完时就产生(不是在调用)
死亡:嵌套的内部函数成为垃圾对象时
<script type="text/javascript"> function fn1() { //此处闭包已经产生(函数提升,内部函数对象已经创建) var a = 3 function fn2() { //若写成var fn2 = function (){...},则是在此处(函数定义完)产生 a++ console.log(a) } return fn2 } var f = fn1() f()//3 f()//4 //在这里闭包还未死亡 f = null //此时闭包对象死亡(包含闭包的对象成为垃圾对象),引用fn1的变量不再引用它
</script>
5、闭包的应用
定义特定功能的js模块文件
将所有的数据和功能都封装在一个函数内部(私有)
只向外暴露一个包含多个方法的对象或者函数
模块使用的地方,直接引入
但是需要注意的是,要么接收,要么在js中定义完直接执行,否则会立即释放
<script type="text/javascript" src="xxx.js"></script>
6、闭包的缺点
函数执行完以后,内部局部变量没有释放,占用内存,容易造成内存泄漏
因此能不用闭包就不用,或者及时释放(很重要)
<script type="text/javascript"> function fn1() { var arr = new array[100000] function fn2() { console.log(arr.length) } return fn2; } var f = fn1(); f(); f = null // 让内部函数成为垃圾对象---》回收闭包
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix