核心定义

闭包 (Closure) 是函数与其声明时的词法环境的组合。当函数被创建时,它会 ” 记住 ” 自己定义时的作用域链,即使该函数在调用时已离开原作用域,仍能访问那些变量。

闭包的形成只需满足两个条件:

  1. 函数嵌套:一个函数内部定义了另一个函数
  2. 内部函数引用了外部函数的变量

解决的核心痛点:在函数式编程中,需要让函数携带其执行环境,实现数据封装和函数工厂模式。

核心命题与原则

运行机制

运作流程

flowchart TD
    A[函数定义] --> B[创建 Scope 属性]
    B --> C[保存当前作用域链]
    C --> D{函数被调用?}
    D -->|是| E[沿着 Scope 访问变量]
    D -->|否| F[等待调用]
    E --> G[返回结果]
    G --> H{"闭包引用<br/>仍存在?"}
    H -->|是| I[保留作用域链]
    H -->|否| J[垃圾回收]

关键区别

维度闭包IIFE
核心逻辑函数记住定义时的作用域函数定义后立即执行并销毁
生命周期长期存在,保存状态执行后立即销毁
适用场景数据封装、函数工厂避免污染全局、模块模式

应用场景与反模式

适用场景

  • 数据封装:创建只能通过特定方法访问的私有变量
  • 函数工厂:创建具有不同配置的函数
  • 模块模式:实现模块化的代码组织
  • 事件处理:在回调中访问定义时的变量

误用与反模式

  • 内存泄漏:闭包长期持有对大型对象的引用
  • 循环闭包:在循环中创建闭包时捕获相同的变量引用(用 let 解决)

知识图谱

flowchart TB
    Closure[闭包<br/>Closure] -->|基于| LexScope[词法作用域]
    Closure -->|依赖| ExecCtx[执行上下文]
    Closure -->|访问| ScopeChain[作用域链]

    LexScope -->|组成| LE[词法环境]

    Closure -->|应用| Module[模块化编程]
    Closure -->|应用| FP[函数式编程]
    Closure -->|应用| Event[事件处理]

    Closure -->|风险| Memory[内存泄漏]

    JS[JavaScript] -->|包含| Closure
    ScopeChain -->|属于| ExecCtx

    style Closure fill:#f99,stroke:#333,stroke-width:2px
    style LexScope fill:#9ff,stroke:#333
    style ScopeChain fill:#9f9,stroke:#333

相关概念