闭包的主要作用:实现数据私有,函数内定义的私有变量,外面可以使用访问,但不可以修改。
以统计调用次数的函数为例:
普通形式:
javascript">let a = 0;function fn() {a++;console.log(`a: ${a}`);}
闭包形式:
javascript"> 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
的影响。
闭包产生的内存泄漏:
示例代码:
javascript"> function fn() {let count = 1function fun() {count++console.log(`函数第${count}次执行`)}return fun}const res = fn()res() // 2res() // 3
谁会产生内存泄漏:count变量
借助于垃圾回收机制的 标记清除法 可以看出:
① result 是一个全局变量,代码执行完毕不会立即销毁
② result 使用 fn 函数
③ fn 用到 fun 函数
④ fun 函数里面用到 count
⑤ count 被引用就不会被回收,所以一直存在
注意:不是所有内存泄漏都要手动回收,比如react里面很多闭包不能回收