标准答案

  1. 定义:一个函数引用了外层作用域里的变量,并且这个函数在外层函数执行结束后仍然可能被调用,那么这些被引用的变量就会随着函数一起保留下来。闭包不是特殊语法,而是词法作用域和函数作为一等公民共同产生的结果。
  2. 用途:闭包常用于封装私有状态、函数工厂、缓存结果、保存回调上下文和实现模块化。比如计数器函数每次调用都能记住自己的 count,就是因为内部函数持有了外层变量。
  3. 风险:闭包本身不是内存泄漏。真正的风险是闭包被长期引用时,它引用的外层变量也不会被回收。如果闭包里持有大对象、DOM 节点、定时器或事件监听,又没有清理,就可能造成内存占用增长。
  4. 工程处理:需要在组件卸载、页面销毁或任务结束时解绑监听、清理定时器,并避免把不再需要的大对象放进长期闭包。

题目解析

回答闭包时,最好同时讲“是什么、能做什么、风险在哪里”。只背“函数内部返回函数”不够,因为函数嵌套不一定形成有实际意义的闭包。

闭包的内存风险来自引用关系。只要闭包还可达,被它引用的词法环境也会继续可达。

代码示例

计数器是最容易解释闭包的例子:外层函数已经执行完,但 count 仍被内部函数保存。

JavaScript
function createCounter() {
  let count = 0

  return function increment() {
    count += 1
    return count
  }
}

const counter = createCounter()
counter() // 1
counter() // 2

常见误区

  • 把闭包等同于函数嵌套。函数嵌套只是形式,关键是内部函数引用了外层变量并可能在外层执行结束后继续使用。
  • 误以为闭包一定会导致内存泄漏。只有长期持有不再需要的对象时才会形成问题。
  • 只会背定义,不会说私有变量、缓存、事件回调这些使用场景。

作者信息