闭包
什么是闭包?
概念: 一个函数对周围状态的引用捆绑在一起,内层函数中访问到其他外层函数的作用域
简单理解: 闭包=内层函数+引用的外层函数变量
先看一组简单的闭包代码
一句话可以概括: 闭包就是能够读取其他函数内部变量的函数,或者子函数在外调
用,子函数所在的父函数的作用域不会被释放。
function outer(){
const a=1;
function f(){
consol.log(a);//就形成了闭包
};
f();
};
outer();
通常会在使用一个函数包裹住闭包结构,以起到对变量保护的作用
闭包有些容易引起歧义的地方:
闭包的2个注意点:
- 闭包一定有return吗?
- 闭包一定会有内存泄露吗?
闭包什么时候用到return
外部如果想要使用闭包的变量,则此时需要return
function outer(){
const a=1;
//return 返回出去这个局部变量a外面就能使用了
return function f(){
consol.log(a);//就形成了闭包
};
f();
};
outer();
闭包应用: 实现数据的私有
比如,我们要统计函数调用次数,函数调用一次,就++
常规写法
let count=1
function fn(){
count++
console.log('函数被调用了$`{count}次`')
}
fn() //2
fn() //3
但是这个count是个全局变量,很容易修改
闭包写法
function{
let count=1
function fun(){
count++
console.log('函数被调用了$`{count}次`')
}
return fun
}
const result=fn()
result() //2
result() //3
这样实现了数据私有,无法直接修改count
闭包-内存泄露
上方代码谁会存在内存泄露?count变量
借助于垃圾回收机制的 标价清除法可以看出
- result是你一个全局变量,代码执行完毕不会立即销毁
- result使用fn函数
- fn通道fun函数
- fun函数里面用到count
- count被引用就不会被回收,所以一直存在
此时:闭包引起了内存泄露
注意:
- 不是所有的内存泄露都要手动回收的
- 比如react里面很多闭包不能回收的
闭包形成的条件:
- 函数的嵌套
- 内部函数引用外部函数的局部变量,延长外部函数的变量生命周期
闭包的用途: - 模仿块级作用域
- 保护外部函数的变量 能够访问函数定义时所在的词法作用域(阻止其被回 收)
- 封装私有化变量
- 创建模块
闭包的优点:
延长局部变量的生命周期
简述闭包的问题以及优化
闭包的缺点:占用内层空间 大量使用闭包会造成 栈溢出
优化:由于闭包会一直占用内存空间,直到页面销毁,我们可以主动将已使用的闭包销毁:
将闭包函数赋值为null 可以销毁闭包