栈/堆内存

栈/堆内存

栈内存

主要存储基本数据类型的值( NumberStringBooleanUndefinedNullSymbolBigInt

还存储变量的引用地址(指向堆内存的对象)

函数调用时的执行上下文也会压入栈中

内存是连续分配的,大小固定,内存的访问、分配、释放都非常快

1
2
3
4
5
6
7
8
9
let a = 10; // 基本数据类型,存储在栈内存中
let b = "Hello"; // 基本数据类型,存储在栈内存中
let c = null; // 基本数据类型,存储在栈内存中

function foo(x) {
let y = 20; // 局部变量,存储在栈内存中
console.log(x + y);
}
foo(5); // 函数调用时,函数的执行上下文会被压入栈中

堆内存

存储复杂数据类型的值(对象、数组、函数等)

还存储对象的属性、方法 & 数组的元素

内存非连续分配,大小不固定,分配和释放都慢,因为需要动态管理内存,而且需要通过引用地址间接访问

1
2
3
4
5
6
7
let obj = { name: "Alice", age: 30 }; // 对象存储在堆内存中
let arr = [1, 2, 3]; // 数组存储在堆内存中

// 栈内存中存储的是引用地址
let refObj = obj; // refObj 和 obj 指向同一个堆内存地址
refObj.age = 35; // 修改 refObj 的属性会影响 obj
console.log(obj.age); // 输出: 35
1
2
3
4
5
let obj1 = { name: "Alice" };
let obj2 = obj1; // 复制引用地址
obj2.name = "Bob";
console.log(obj1.name); // 输出: Bob
console.log(obj2.name); // 输出: Bob

对比

  • 基本数据类型 vs 引用数据类型
    • 基本数据类型直接存储在栈内存中,操作的是实际值。
    • 内存存储引用数据类型内存中只存储引用地址
  • 引用传递 vs 值传递
    • 基本数据类型是值传递:赋值或作为参数传递时,会复制一份新的值
    • 引用数据类型是引用传递:赋值或作为参数传递时,复制的是引用地址多个变量可能指向同一个堆内存地址