什么是闭包
概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域
简单理解:闭包 = 内层函数 + 外层函数的变量
代码:
function outer(){
const a = 1
function f(){
console.log(a)
}
f()
}
outer()
如何理解 需要内层函数调用外层函数变量才能产生闭包?
我们可以通过谷歌浏览器断点的方式,查看代码是否存在闭包,如果出现Closure,说明存在闭包。
function outer(){
const a = 1
function f(){
console.log(a)
}
f()
}
outer()
function outer(){
const a = 1
function f(){
console.log(1111)
}
f()
}
outer()
内层函数没有调用外层函数的变量,所以不存在闭包。
闭包的作用
防止全局变量被污染
let i = 0;
function fn(){
i++
console.log(`被调用了${i}次`)
}
i = 1000
fn() // 函数内部的i++会被全局修改,导致输出结果 被调用了1001次
// 可以用闭包来解决这个问题
function count(){
let i = 0
function fn(){
i++
console.log(`被调用了${i}次`)
}
return fn
}
const fun = count()
i = 1000
fun() // 被调用了1次
fun() // 被调用了2次
闭包造成的影响,因为标记清楚法在页面关闭前会将被调用的变量一直保存于内存之中,很可能会造成内存泄漏。
解决闭包造成的内存泄漏
1、释放对外部变量的引用:在不需要使用闭包的地方,及时释放对外部变量的引用。在上面的示例中,可以在使用完变量后,手动将其设为null。
function outerFunction() {
var data = 'Hello, world!';
function innerFunction() {
console.log(data);
data = null;
}
return innerFunction;
}
var inner = outerFunction();
inner(); // 输出‘Hello, world!’
2、使用立即执行函数:将闭包放入立即执行函数中,当函数执行完毕后,闭包中引用的外部变量会被释放。
var inner = (function() {
var data = 'Hello, world!';
function innerFunction() {
console.log(data);
}
return innerFunction;
})();
inner(); // 输出‘Hello, world!’
需要根据场景选择内存释放的时机,以上两端代码只是演示如何释放内存。