闭包通过词法作用域和函数对象对自由变量的持久引用,保存外部函数中被实际引用的变量(非复制值),使其在外部函数执行完毕后仍驻留内存;多个闭包可共享同一变量,let/const 保证循环中独立绑定,var 则易导致共享问题。

闭包函数能访问并保存外部函数的变量,靠的是词法作用域和函数对象对自由变量的持久引用——不是复制值,而是“记住”变量所在的环境。
闭包如何捕获外部变量
当一个内部函数在定义它的外部函数返回后,仍能访问外部函数的局部变量,就形成了闭包。JavaScript 引擎会为这个内部函数创建一个闭包环境,把外部函数中被它引用的变量(即“自由变量”)保留在内存中,不会随外部函数执行结束而销毁。
- 变量必须在内部函数中被实际引用(哪怕只是读取),才会被纳入闭包;未使用的变量会被垃圾回收
- 闭包保存的是变量的引用,不是快照值。如果外部变量后续被修改,闭包里看到的就是最新值
- 多个闭包可以共享同一个外部变量(比如循环中创建的多个函数)
常见写法:返回函数并使用外层参数或局部变量
最典型的闭包模式是外部函数返回一个内部函数,该内部函数访问外部函数的参数或 let/const 声明的变量:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
function createCounter(initial) {
let count = initial; // 局部变量
return function() {
count++; // 访问并修改外部变量
return count;
};
}
const counter = createCounter(10);
console.log(counter()); // 11
console.log(counter()); // 12
这里 count 被闭包持续持有,每次调用 counter() 都操作的是同一个 count 实例。
注意 var 和 let/const 的差异
用 var 声明变量时,在循环中创建闭包容易出问题,因为 var 是函数作用域,所有迭代共享同一个变量:
- 用
let或const声明则为每次迭代创建独立绑定,闭包能正确捕获各自值 - 也可用立即执行函数(IIFE)或给函数传参方式绕过
var的问题
闭包变量的生命周期
只要闭包函数还存在(比如被赋值给全局变量、作为回调保留、被其他对象引用),它所依赖的外部变量就不会被回收。即使外部函数早已执行完毕,这些变量仍驻留内存。
- 过度使用闭包可能引发内存泄漏,尤其在 DOM 事件监听或定时器中长期持有大对象
- 解除引用(如将闭包函数设为
null)有助于垃圾回收释放相关变量
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










