Js闭包Closure 及 其可能产生的内存泄漏问题
闭包的主要作用:实现数据私有,函数内定义的私有变量,外面可以使用访问,但不可以修改。
以统计调用次数的函数为例:
普通形式:
let a = 0;
function fn() {
a++;
console.log(`a: ${a}`);
}
闭包形式:
function count() {
let a = 0;
function fn() {
a++;
console.log(`a: ${a}`);
}
return fn;
}
const fun = count();
一,为什么调用时要使用fun() 而不是直接count():
count()
只是返回了fn
函数的引用,而没有执行fn
函数。fun()
是对fn
函数的调用,它会执行fn
函数的逻辑,即对局部变量a
进行递增操作并打印其值。
因此,为了执行 fn
函数的逻辑,你需要将 count()
的返回值赋值给一个变量,然后调用这个变量来执行 fn
函数。
二,原理:
闭包 fn
保留了对 count
函数内部局部变量 a
的引用,即使 count
函数执行完毕,a
的值仍然被保留。而在全局作用域中定义的 a
是一个新的变量,与闭包内部的 a
没有关联。因此,每次调用 fun()
都会操作闭包内部的 a
,而不会受到全局变量 a
的影响。
闭包产生的内存泄漏:
示例代码:
function fn() {
let count = 1
function fun() {
count++
console.log(`函数第${count}次执行`)
}
return fun
}
const res = fn()
res() // 2
res() // 3
谁会产生内存泄漏:count变量
借助于垃圾回收机制的 标记清除法 可以看出:
① result 是一个全局变量,代码执行完毕不会立即销毁
② result 使用 fn 函数
③ fn 用到 fun 函数
④ fun 函数里面用到 count
⑤ count 被引用就不会被回收,所以一直存在
注意:不是所有内存泄漏都要手动回收,比如react里面很多闭包不能回收