JS中的闭包
什么是闭包?
闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁
function sum (){
let i = 0
return function(){
console.log(i++)
}
}
let test = sum()
test()
test()
test()
以上就是一个闭包,笼统的说就是函数的返回值是一个函数,在这个函数里面访问了函数内部的变量,外部执行这个返回值使得外部可以间接的访问到函数内部的变量
闭包的特点
- 根据js的垃圾回收机制中的引用计数可以知道,在闭包中参数与变量不会被垃圾回收机制回收,所以可将一个变量长期驻扎在内存当中可用于循环取值
- 方便调用上下文的局部变量
- 使用闭包可以避免全局变量的污染。
使用场景
- 函数的防抖以及节流
- 封装JS模块
- 重用一个变量,防止变量在外部被污染
例如经典的for循环问题
// 预期结果 1 2 3 4 5
for (var i = 1; i <= 5; i++) {
setTimeout(()=> {
console.log(i)
}, i * 100)
}
// 实际结果 6 6 6 6 6
使用闭包来解决
for (var i = 1; i <= 5; i++) {
( (j) =>{
setTimeout(function timer() {
console.log(j)
}, j * 100)
})(i)
}
缺点
-
内存消耗
通常来说,函数的活动对象会随着执行期上下文一起销毁,但是,由于闭包引用另外一个函数的活动对象,因此这个活动对象无法被销毁,这意味着,闭包比一般的函数需要更多的内存消耗。尤其在IE浏览器中需要关注。由于IE使用非原生javascript对象实现DOM对象,因此闭包会导致内存泄露问题 -
性能问题
使用闭包时,会涉及到跨作用域访问,每次访问都会导致性能损失。