JavaScript变量在内存中的堆栈存储
栈
主要用于
- 存放 基本类型变量
- 存放函数调用信息
- 记录执行上下文
特点:
存取速度快
占用空间小
自动分配释放
基础类型会存放与栈,引用类型会存放在堆
案例:以下代码为什么输出
50 30
javascript
function fn(obj) {
obj = { m: 50 }
console.log(obj.m)
}
const o = { m: 30 }
fn(o)
console.log(o.m)解析
这段代码的关键在于理解函数参数的按值传递(Call by Value)以及引用类型的存储方式。
1. 初始状态
javascript
const o = { m: 30 }- 堆内存(Heap):创建了一个对象
{ m: 30 },假设它的内存地址是0x001。 - 栈内存(Stack):变量
o存储了该对象的引用(即地址0x001)。
2. 调用函数 fn(o)
javascript
fn(o)- 函数
fn被调用,创建了一个新的执行上下文。 - 参数传递:JS 中函数参数是按值传递的。
- 这里传递的是变量
o的值,也就是地址0x001。 - 所以,函数内部的局部变量
obj初始时也指向地址0x001。 - 此时:
o->0x001,obj->0x001。
- 这里传递的是变量
3. 函数内部执行
javascript
obj = { m: 50 }- 堆内存:创建了一个新对象
{ m: 50 },假设它的地址是0x002。 - 赋值操作:将这个新地址
0x002赋值给局部变量obj。 - 关键点:这个赋值操作切断了
obj与原对象0x001的联系。- 此时:
obj->0x002。 - 外部变量
o仍然指向0x001,完全没有受到影响。
- 此时:
javascript
console.log(obj.m)- 输出
obj指向的新对象(0x002)的m属性,即 50。
4. 函数执行结束
- 函数上下文销毁,局部变量
obj释放。 - 外部代码继续执行。
javascript
console.log(o.m)- 访问外部变量
o。 o始终指向原对象(0x001),其内容{ m: 30 }从未被修改。- 输出 30。
总结图示
