闭包的定义
一个函数的执行空间以及环境中所在的局部变量。
代码举例及运行结果如下:
function fn(){
let a=10;
return function(){
console.log(a);
}
}
const closure=fn();
closure();
console.log(a);
其中,外部函数名称为fn,内部定义局部变量为a并赋值为10,返回的函数功能为打印函数内部的局部变量a;在全局环境下,通过调用fn函数得到一个新函数。定义closure变量,保存新函数引用地址,并执行这个closure函数,得到结果为10,说明已经访问到了fn内的局部变量a。而如果在全局环境中直接访问变量a是会报错的。
能访问到局部变量的原因:
JS的垃圾回收机制
JS中内存为自动分配。垃圾回收方法有引用计数和标记清理。其中引用计数原理为统计引用次数确定该部分内存是否回收,由于弊端太多所以不经常使用。而目前主流的标记清理为将未被引用的变量标记,并清理。
以上面代码为例,全局变量closure引用为renturn的匿名函数,而这个匿名函数中涉及到了对于局部变量a的引用。由于这样一系列的引用,导致了系统在垃圾回收时这些内存空间无法回收销毁,这就能够访问到了。
闭包的优点
1.局部变量能够常驻内存,随时可以访问。
2.不会污染全局变量名称定义。
3.通过闭包可以构造私有变量,而私有变量不能直接访问,只能通过闭包函数访问操作,确保了数据安全。
闭包的缺点
由于局部变量能够常驻内存,这就导致无法及时释放内存空间,导致整体内存空间减少,也即内存泄漏。
内存泄漏的处理
在确定不再使用闭包时,将保存闭包引用的变量设为null。