javascript中引用类型共享本质是地址复用,变量存储堆内存地址而非值本身;直接赋值或传参时复制地址,导致多变量指向同一对象,修改属性会相互影响,需用浅拷贝或深拷贝避免。

JavaScript 中没有真正意义上的“指针”,引用类型的数据共享不是通过指针实现的,而是通过内存地址的隐式引用——变量保存的是对象在堆内存中的地址,多个变量若指向同一地址,就实现了数据共享。
引用类型共享的本质是地址复用
当你创建一个对象、数组或函数时,JavaScript 引擎会在堆内存中分配空间并返回一个内存地址。变量本身并不存储值,而是存储这个地址。如果把该地址赋给另一个变量,两个变量就“指向”同一块堆内存。
- 修改其中一个变量的属性(如
obj.a = 2),另一个变量立刻可见变化,因为它们访问的是同一块内存 - 重新赋值变量(如
obj = {})只是让该变量指向新地址,不影响其他变量 - 这和 C/C++ 中的指针不同:你不能获取或运算地址,也不能进行指针偏移操作
常见共享场景与易错点
以下操作都会导致共享行为,但容易被误认为是“复制”:
-
直接赋值:
const a = {x: 1}; const b = a;→a和b共享同一对象 -
函数参数传递:
function fn(obj) { obj.y = 2; } fn(a);→ 原对象被修改 -
数组/对象方法返回引用:
const arr = [1,2]; const ref = arr.slice(0);→slice()浅拷贝,若元素是对象仍共享
如何避免意外共享?用浅拷贝或深拷贝
需要独立副本时,不能依赖赋值,而要显式拷贝:
-
浅拷贝(只拷贝第一层):
{...obj}、Array.from(arr)、arr.slice()、Object.assign({}, obj) -
深拷贝(递归拷贝所有层级):
JSON.parse(JSON.stringify(obj))(有局限,不支持函数、undefined、Date 等),或使用structuredClone()(现代浏览器支持)、第三方库如 Lodash 的_.cloneDeep()
检测是否共享:用严格相等判断引用关系
两个变量是否指向同一对象,可用 === 判断:
const a = {}; const b = a; console.log(a === b); // trueconst c = {}; console.log(a === c); // false- 注意:
==在对象比较中行为同===,不触发类型转换
不复杂但容易忽略:所谓“指针共享”,其实是 JS 引擎自动管理的引用机制,开发者只需理解变量存的是地址,而非值本身,就能准确预判数据变更的影响范围。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











