JavaScript局部变量在函数执行结束后自动销毁:原始类型存于栈中,函数结束即同步释放;引用类型存于堆中,由GC根据可达性回收;闭包可延长变量生命周期。

JavaScript 中局部变量在函数执行结束后自动销毁,主要靠作用域规则和内存管理机制协同完成,不是靠“手动清理”,也不依赖程序员干预。
栈内存中的原始类型变量立即释放
函数内部用 let、const 或 var 声明的原始类型(如 number、string、boolean、undefined、null、symbol)都存放在调用栈中。每次函数调用会生成一个栈帧,里面包含这些变量的值和执行上下文。
- 函数执行一结束,V8 引擎直接移动栈顶指针(ESP),整个栈帧被弹出
- 这个过程是同步的、毫秒级的,不经过垃圾回收器
- 例如:
function f() { let x = 100; return x * 2; },f()返回后,x在栈中已不复存在
堆内存中的引用类型靠 GC 判定是否可回收
如果局部变量是对象、数组、函数等引用类型,它们实际数据存在堆中,栈里只存一个指向堆地址的引用。函数结束时,栈里的引用消失,但堆中对象不会立刻销毁。
- 只有当该对象不再被任何活跃执行上下文或全局变量引用时,才被标记为“不可达”
- V8 的垃圾回收器(GC)会在合适时机(比如新生代空间不足时)启动 Mark-Sweep 或 Scavenge 算法回收它
- 例如:
function g() { return { name: "Alice" }; },返回后若没人接住这个对象,它很快会被 GC 回收
闭包会延长局部变量生命周期
如果函数返回了一个内部函数,并且该内部函数访问了外层函数的局部变量,那么这些变量不会随外层函数结束而销毁。
立即学习“Java免费学习笔记(深入)”;
- 因为它们仍被闭包函数“捕获”,属于活跃引用链的一部分
- V8 会把这部分变量从栈转移到堆中长期保存,直到闭包函数本身也不再被引用
- 这是唯一让局部变量“活过函数结束”的常见情况
变量声明方式不影响销毁时机,只影响作用域范围
var、let、const 声明的局部变量,只要不出现在闭包中,都会在函数退出时失去引用。
-
var是函数作用域,let/const是块级作用域,但销毁逻辑一致:离开作用域即失效 - 哪怕
let变量在 if 块里声明,块结束时它就不可访问,对应内存也进入待回收状态 - 真正决定是否立刻释放的,是变量类型(栈 or 堆)和是否还有有效引用


















