函数与作用域的关系
闭包让函数记住自己创建时的作用域。它常用于保存私有状态、封装工具函数和处理异步回调。
适用场景
- 计数器和缓存
- 函数工厂
- 防抖节流
- 事件回调中保存上下文
技术点总览
| 技术点 | 主要作用 |
|---|---|
| 函数可以访问外层变量 | JavaScript 使用词法作用域,函数能访问哪些变量取决于它写在哪里。内部函数可以读取外部函数里的变量。 |
| 闭包保存私有状态 | 当内部函数被返回后,外部函数已经执行结束,但被内部函数引用的变量仍然会保留下来。 |
| 函数工厂生成不同函数 | 闭包可以把配置保存起来,然后生成带有不同默认行为的函数。 |
分批介绍
函数可以访问外层变量
JavaScript 使用词法作用域,函数能访问哪些变量取决于它写在哪里。内部函数可以读取外部函数里的变量。
JS
1function outer() {2const name = 'Sakura'34function inner() {5return name6}78return inner()9}
闭包保存私有状态
当内部函数被返回后,外部函数已经执行结束,但被内部函数引用的变量仍然会保留下来。
JS
1function createCounter() {2let count = 034return function add() {5count += 16return count7}8}910const add = createCounter()11add()12add()
函数工厂生成不同函数
闭包可以把配置保存起来,然后生成带有不同默认行为的函数。
JS
1function createPrefixLogger(prefix) {2return function log(message) {3console.log(prefix + ': ' + message)4}5}67const warn = createPrefixLogger('warn')8warn('network slow')
使用建议
- 闭包会延长变量生命周期。
- 不要长期保存不再需要的大对象。
- 循环和异步中使用闭包时要确认保存的是不是当前值。
小结
函数与作用域的关系 的重点不是记住某个 API,而是理解它解决的问题、适合的场景以及和其它技术点之间的关系。把每个小知识点拆开看,再组合到真实业务里,代码会更有规律,也更容易维护。
