什么是闭包?请举例说明其应用场景和潜在问题
闭包是指一个函数能够访问其外部函数作用域中的变量,即使外部函数已经执行完毕。
形成条件
- 函数嵌套
- 内部函数引用外部函数的变量
- 内部函数被返回或传递到外部
经典示例
function createCounter() {
let count = 0 // 外部变量
return {
increment() { return ++count },
decrement() { return --count },
getCount() { return count }
}
}
const counter = createCounter()
counter.increment() // 1
counter.increment() // 2
counter.getCount() // 2应用场景
- 数据私有化(模块模式)
- 函数柯里化
- 防抖/节流
- 缓存(记忆化函数)
// 记忆化函数
function memoize(fn) {
const cache = {}
return function (...args) {
const key = JSON.stringify(args)
if (key in cache) return cache[key]
return cache[key] = fn.apply(this, args)
}
}潜在问题
- 内存泄漏:闭包引用的变量不会被 GC 回收
- 变量共享:循环中的闭包共享同一变量
// 经典问题:循环中的闭包
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0) // 3, 3, 3
}
// 解决方案 1:let
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0) // 0, 1, 2
}
// 解决方案 2:IIFE
for (var i = 0; i < 3; i++) {
((j) => setTimeout(() => console.log(j), 0))(i)
}