相信很多人被这些问题困扰过。今天我们不啰嗦,一句话 + 一个经典例子,让你真正吃透闭包原理。
📌一句话理解闭包:
闭包是函数 + 它能访问的自由变量的组合。换句话说:
函数内部访问了函数外部的变量,这个函数就“形成了闭包”。🔧经典闭包示例:
js
复制编辑
function createCounter() {
let count = 0
return function () {
count++
console.log(count)
}
}
const counter = createCounter()
counter() // 1
counter() // 2
🔍这里发生了什么?
- createCounter() 返回了一个匿名函数;
- 这个匿名函数记住了 count 变量;
- 每次调用 counter(),它都还能访问 count 并累加。
这就形成了闭包!
🎯闭包的作用:
应用场景说明数据私有化外部无法直接修改 count,只能通过闭包修改记忆缓存闭包可用于缓存上一次结果函数工厂可以返回一组带有私有状态的函数
🧠常见误区:
js
复制编辑
var funcs = []
jrhz.infofor (var i = 0; i < 3; i++) {
funcs.push(function () {
console.log(i)
})
}
funcs[0]() // 3 ❗不是 0
funcs[1]() // 3 ❗不是 1
funcs[2]() // 3 ❗不是 2
为什么?因为所有函数都共享了同一个 i(3),而不是各自记住一个。
✅正确做法(使用 let 块级作用域):
js
复制编辑
for (let i = 0; i < 3; i++) {
funcs.push(() => console.log(i))
}
或者用立即执行函数(IIFE)创建闭包:
js
复制编辑
for (var i = 0; i < 3; i++) {
(function (j) {
funcs.push(() => console.log(j))
})(i)
}
🚨闭包缺点:内存泄漏
因为闭包长期引用外部变量,导致这些变量无法被垃圾回收,特别是搭配 DOM、定时器使用时。
✅解决方式:及时解除引用或封装合理作用域。
https://blog.csdn.net/qqqdqd/article/details/149209167
https://blog.csdn.net/qqqdqd/article/details/149209090
https://blog.csdn.net/qqqdqd/article/details/149208922
https://blog.csdn.net/qqqdqd/article/details/149209254