局部变量在函数执行完毕后通常销毁,但若被闭包引用则继续存活;var声明属函数作用域,let/const属块级或函数作用域,超出作用域即不可访问,而闭包可延长其生命周期。

局部变量在函数执行完毕后是否销毁,关键看有没有被“留住”——不是函数一结束就必然消失,而是看有没有其他代码还在引用它。
销毁是默认行为:函数退出,变量通常立即失效
函数内部用 let、const 或 var 声明的变量,在函数执行结束时,如果没有被外部保留,就会失去访问路径,内存可被回收。
- var 声明的变量属于函数作用域,函数调用结束即不可再访问
-
let/const 声明的变量属于块级或函数作用域,超出作用域后直接报
ReferenceError - 比如函数返回一个普通值(如数字、字符串),函数内声明的变量不会被带走
保留是特殊机制:闭包让局部变量“活下来”
当函数返回另一个函数,并且这个内部函数引用了外层函数的局部变量,JavaScript 就会形成闭包——外层函数虽然执行完了,但它的局部变量仍保留在内存中,供内部函数持续使用。
- 这不是 bug,是语言设计的特性,用于实现私有数据、计数器、配置封装等
- 例如:
function createCounter() { let count = 0; return () => ++count; },每次调用返回的函数都共享并维护着同一个count - 只要返回的函数还存在(比如被赋值给某个变量、绑定为事件监听器),
count就不会销毁
容易误判的几种情况
有些看似“变量还在”,其实并不是原变量被保留,而是值被复制或重新创建了。
立即学习“Java免费学习笔记(深入)”;
-
异步回调中访问变量:如果回调里用了
var i循环中的变量,往往拿到的是最后的值;换成let i才能为每次迭代创建独立绑定 -
隐式全局变量:没写
let/const/var就直接赋值(如i = 10),变量实际挂到了全局,根本没进局部作用域 - 对象属性或数组元素:函数返回了一个包含局部变量值的对象,那只是值拷贝,原变量本身仍按规则销毁
怎么判断一个局部变量到底销毁没?
看它是否还有活跃的引用链:如果没有任何函数、对象或闭包持有对它的引用,V8 引擎会在下一次垃圾回收时清理它。
- 开发者工具中可查看内存快照,观察变量是否仍被 closure 持有
- 频繁创建闭包并长期持有大对象,可能导致内存泄漏
- 不需要长期保留时,可手动解除引用(如将变量设为
null)帮助回收


















