javascript中对象是引用类型,变量存储的是指向堆内存中对象的地址,而非对象本身;栈存固定大小的地址指针,堆存动态大小的对象数据,赋值时复制地址导致多变量共享同一对象。

JavaScript 中对象是引用类型,它的内存分配不是把整个对象塞进变量里,而是“变量存地址,对象存别处”。理解这一点,关键在分清栈和堆各自管什么、怎么联动。
栈里只存“指针”,不是对象本身
当你写 let user = { name: '李四' };,JS 引擎会在:
-
栈内存中为变量
user分配一小块固定空间,里面存的只是一个十六进制地址(比如0x001); -
堆内存中开辟一块动态空间,真正存放
{ name: '李四' }这个对象数据; - 栈中的地址
0x001指向堆中那块数据——这就是“引用”的本质。
多个变量指向同一块堆内存,改一个就全变
引用复制不等于拷贝对象。例如:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
let a = { age: 25 };→ 栈存指针,堆存对象; -
let b = a;→ 栈中新增变量b,但值仍是同一个地址0x001; -
b.age = 30;→ 通过地址找到堆里的对象,直接修改它; - 此时
a.age也变成30,因为a和b指向的是堆中同一份数据。
基本类型和引用类型的对比很清晰
区别不在“能不能变”,而在“怎么存、怎么传”:
- 基本类型(string、number、boolean 等):值直接存在栈里,赋值或传参时复制的是值本身;
- 引用类型(object、array、function 等):栈里只存地址,赋值或传参时复制的是地址,所以操作的是同一块堆内存;
- 判断是否相等也不同:基本类型比值,引用类型比地址(
{} === {}是false,哪怕内容一模一样)。
想隔离修改?得手动创建新对象
如果希望 b 的改动不影响 a,就得切断引用关系,让 b 指向堆中另一份副本:
- 对象:用
Object.assign({}, a)、展开运算符{...a}或结构赋值; - 数组:用
[...a]、a.slice()、a.concat(); - 深层嵌套需用深拷贝(如
JSON.parse(JSON.stringify(a))或结构化克隆structuredClone(a))。
不复杂但容易忽略:所谓“对象是引用类型”,不是说它多特殊,只是 JS 把大而不确定的东西放堆里管理,再用轻量指针连到栈上——这是内存效率和语言设计的自然选择。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










