什么是闭包?
闭包是函数和其词法环境的组合。
1 | function outer() { |
作用
- 封装私有变量
- 创建工厂函数
- 实现模块模式
经典例子
计数器
1 | function createCounter() { |
私有变量
1 | function Person(name) { |
注意事项
- 内存泄漏:闭包可能导致变量无法释放
- 性能:过度使用影响性能
总结
闭包是 JavaScript 最强大的特性之一,它赋予函数维护私有状态的能力,也是模块化、迭代器、回调和许多高级模式的基础。合理使用闭包可以写出简洁优雅的代码,但滥用则可能导致内存泄漏和调试困难。
闭包在模块化中的应用
1 | const counter = (function() { |
性能和优化
- 避免在循环中创建不必要的闭包
- 使用
let/const代替var防止意外共享 - 释放引用:将不再使用的闭包赋值为
null
闭包与事件处理
1 | button.addEventListener('click', (function() { |
常见误区
- 认为闭包永远存在:只要有引用就会保持
- 认为闭包创造全局变量:闭包本身是局部的
调试闭包
- 使用 Chrome DevTools 的 Scope 窗口查看闭包变量
- heap snapshot 分析函数闭包
小结
掌握闭包需要理解作用域链与垃圾回收的交互。不断练习示例,并阅读开源库源码(如 jQuery、Lodash)以体会闭包的实际用法。
闭包是 JavaScript 强大特性。理解它能写出更好代码,但要小心内存使用。
练习题
- 写出一个闭包实现的缓存函数。
- 使用闭包创建一个计时器。
扩展阅读
- JavaScript 权威指南中的闭包章节
- Paul Irish 关于闭包的演讲
代码审查建议
在审查代码时留意函数内部是否创建了不必要的闭包,以及是否安全释放了外部引用。
练习答案示例
1 | function memoize(fn) { |
补充闭包行 1
补充闭包行 2
补充闭包行 3
补充闭包行 4
补充闭包行 5
补充闭包行 6
补充闭包行 7
补充闭包行 8
补充闭包行 9
补充闭包行 10