函数执行上下文(fec)按常规在函数执行完毕后立即销毁,不因闭包返回而延长;真正被延长的是其词法环境中变量的生命周期,因闭包持有对该词法环境的引用。

函数执行上下文本身不会因为闭包被返回而延长生命周期,它仍按常规在函数执行完毕后出栈销毁;真正被延长的是其中某些变量的生命周期——这靠的是闭包对词法环境的引用,而非上下文本身存活。
函数执行上下文照常销毁
每次函数调用都会创建一个独立的函数执行上下文(FEC),它经历创建 → 执行 → 销毁三阶段。一旦函数执行结束,该上下文立即出栈、被引擎回收。即使它内部定义了一个返回的闭包,这个 FEC 也不会“暂停”或“冻结”。
- outer() 调用时创建 FEC₁,执行完立刻销毁
- inner 函数对象被 return 出去,但 FEC₁ 已不在调用栈中
- 后续调用 inner() 会创建全新的 FEC₂,与 FEC₁ 无关
变量存活靠的是词法环境引用,不是上下文驻留
闭包保存的不是整个执行上下文,而是其**创建时所在词法环境的引用**。这个环境包含变量对象(如 outer 的局部变量)、作用域链起点等静态结构。
- outer() 执行时,其词法环境里有 let count = 0
- inner 函数在定义时就记住了这个环境(即“捕获”了 count)
- FEC₁ 销毁后,count 变量因被 inner 引用而无法被垃圾回收
- inner 每次执行,都是在自己的新 FEC 中,通过作用域链向上查找到那个被保留的 count
关键区别:上下文 vs 词法环境
执行上下文是运行时的临时容器,只在函数执行期间存在;词法环境是函数定义时确定的静态作用域结构,可被长期持有。
- 上下文(Context):含 this、arguments、执行状态,一次性、不可复用
- 词法环境(Lexical Environment):含环境记录(变量绑定)、外层引用,可被多个闭包共享、跨多次调用延续
- 闭包 = 函数对象 + 词法环境引用,不等于“活的函数上下文”
典型误判场景
容易混淆的情况是看到变量持续可用,就以为“outer 的上下文还活着”。其实:
- console.log(this) 在 inner 里输出的是 global 或 undefined(非 outer 的 this)
- arguments 在 inner 里访问不到 outer 的 arguments(除非显式传入或重命名)
- outer 中用 var 声明的变量虽被提升,但闭包捕获的是词法环境中的绑定,不是上下文快照










