闭包是函数与其创建时词法环境的组合体,执行上下文则是该词法环境的运行时载体;闭包通过[[environment]]内部槽固化父级词法环境,使变量在外层函数退出后仍可访问且不被垃圾回收。

闭包和执行上下文不是两个孤立概念,而是同一运行机制的内外两面:闭包是函数与其词法环境的组合体,而执行上下文正是这个“词法环境”在运行时的具体载体。
闭包依赖执行上下文的词法环境存活
当一个内部函数引用了外层函数的变量,并被返回或传递到外部作用域时,它就形成了闭包。此时,外层函数虽已执行完毕、其执行上下文本该被销毁,但因内部函数仍需访问其中的变量,JavaScript 引擎会保留该执行上下文中的词法环境(Lexical Environment)部分——不是整个上下文,而是环境记录(Environment Record)及其外部引用(outer reference)。
- 词法环境包含:变量声明、参数、函数声明等绑定信息
- 外部引用指向父级词法环境,构成作用域链的基础
- 垃圾回收器不会回收仍被闭包引用的词法环境,哪怕外层函数执行上下文已退出调用栈
每个闭包都绑定着创建时的执行上下文快照
闭包不是运行时动态查找变量,而是固化了函数定义时所处的词法环境。这个“快照”来自函数创建那一刻的执行上下文:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 函数声明时,引擎已确定其父级词法环境(即外层函数或全局环境)
- 该绑定在函数对象内部以 [[Environment]] 内部槽形式存储(ECMAScript 规范术语)
- 每次调用外层函数,都会生成新的执行上下文,进而产生新的词法环境 → 每次返回的闭包都拥有独立的变量副本
执行上下文栈不保留闭包,但词法环境链持续存在
调用栈(Call Stack)只管理活跃的执行上下文:函数返回后,其上下文从栈中弹出。但闭包维系的不是栈帧,而是词法环境链:
- inner() 执行时,其词法环境中 outerVariable 的查找路径为:inner 词法环境 → outer 词法环境(被闭包持有)→ 全局词法环境
- 这条链与调用栈无关,它是静态建立、动态维护的引用关系
- 可通过 Chrome DevTools 的“Scope”面板直观看到 Closure 类型的作用域条目
理解它们的关系,关键看三点
不必死记抽象定义,抓住这三个具象锚点就能理清本质:
- 函数创建时:确定绑定哪个词法环境(即谁是父作用域)
- 函数执行时:通过作用域链查找变量,链首是当前词法环境,链尾是全局环境
- 外层函数退出后:若仍有闭包引用其变量,该部分词法环境不被回收,成为闭包的“数据舱”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










