浅拷贝不区分值传递或引用传递,而是依数据类型自然体现:基本类型复制值(值传递),引用类型复制地址(引用传递)。例如 {...obj} 中,name='李四' 不影响原对象,但 hobbies.push('游泳') 会同步修改原数组。

浅拷贝本身不区分值传递还是引用传递——它只是按数据类型自然表现出这两种行为。关键在于你拷贝的是什么类型的数据,而不是浅拷贝“主动选择”怎么传。
浅拷贝只做一层复制,类型决定行为
浅拷贝(如 Object.assign()、展开运算符 {...obj}、Array.from())会遍历对象第一层属性,对每个属性值分别处理:
- 遇到基本类型(string、number、boolean、null、undefined、symbol、bigint),直接复制值 → 表现为「值传递」,修改新对象该属性不影响原对象
- 遇到引用类型(对象、数组、Date、RegExp 等),只复制其内存地址 → 表现为「引用传递」,新旧对象该属性指向同一块堆内存,改嵌套内容会互相影响
一个例子看清楚区别
下面这段代码同时包含基本类型和引用类型属性:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
const original = {
name: '张三', // 基本类型
age: 25, // 基本类型
hobbies: ['篮球', '读书'], // 引用类型(数组)
info: { city: '北京' } // 引用类型(对象)
};
const shallow = { ...original };
shallow.name = '李四'; // ✅ 只改自己,original.name 还是 '张三'
shallow.hobbies.push('游泳'); // ❌ 影响 original.hobbies → 也变成 ['篮球', '读书', '游泳']
shallow.info.city = '上海'; // ❌ 影响 original.info.city → 也变成 '上海'
不是浅拷贝“混淆”了传递方式,而是它如实反映底层机制
JS 语言本身没有“浅拷贝专属的传递规则”。所谓值传递或引用传递,本质是 JS 对不同类型变量的存储和赋值逻辑:
- 基本类型存栈中,拷贝时拿的是实实在在的值
- 引用类型变量存的是栈里的地址,拷贝时拿的仍是这个地址
- 浅拷贝没能力深入堆内存去复制嵌套结构,所以它把地址照搬过去,自然就延续了引用传递的效果
如何验证当前是值还是引用效果?
最直接的方法:修改拷贝后对象的某项属性,再检查原对象对应位置是否变化:
- 改第一层基本类型属性 → 原对象不变 → 这是值传递的表现
- 改第一层引用类型属性内部的值(如
arr[0]或obj.key)→ 原对象同步变 → 这是引用传递的表现
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










