闭包能持久化访问外部变量,靠的是词法作用域链和对自由变量的引用保持;需满足函数嵌套、内部函数引用外部变量、内部函数逃逸出作用域三条件;引擎将活跃自由变量标记为不可回收,多个闭包可共享或各自捕获变量,修改后所有闭包同步更新。

闭包能持久化访问外部变量,靠的是函数嵌套时形成的词法作用域链和引擎对“自由变量”的保留机制——不是复制值,而是长期持有变量的引用。
必须满足三个基本条件
只有同时满足以下三点,外部变量才能被真正持久化:
- 存在函数嵌套:内部函数在外部函数体内定义
- 内部函数实际引用了外部函数的局部变量或参数(哪怕只是读取一次)
- 该内部函数以某种方式“逃逸”出外部函数作用域,比如被返回、赋值给全局变量、传给定时器或事件监听器
变量不会被回收的关键原因
JavaScript 引擎发现内部函数仍需访问某个外部变量,就会把这个变量标记为“活跃自由变量”,即使外部函数早已执行完毕,它也不会被垃圾回收。
- 多个闭包可共享同一个外部变量(例如循环中用 var 声明的计数器)
- 用 let 或 const 声明时,每次调用外部函数会创建独立绑定,闭包各自捕获自己的那一份
- 修改变量后,所有引用它的闭包看到的都是最新值——因为保存的是引用,不是快照
典型写法:返回函数并操作外层变量
这是最常用也最清晰的实现方式:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
function createCounter(initial) {
let count = initial;
return function() {
count++;
return count;
};
}
const c1 = createCounter(10);
c1(); // 11
c1(); // 12
这里 count 持续存活,是因为 return 的那个匿名函数一直持有对它的引用。
容易忽略的陷阱
不是所有嵌套都会形成有效闭包:
- 如果内部函数没被返回,也没被保存到任何长期存活的地方,变量照常销毁
- 用 var 在循环里声明变量再创建闭包,会导致所有闭包共享最后一个值
- 闭包长期持有大对象或 DOM 节点,又没及时解除引用,可能引发内存泄漏
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










