1️⃣基本类型(Number、String、Boolean、Null、Undefined、Symbol、BigInt)
它们需要浅拷贝或深拷贝吗?
回答:基本类型没有浅拷贝或深拷贝的说法,因为它们是按值传递的。
-
基本数据类型 是不可变值
-
基本数据类型 赋值时直接复制值本身
-
基本数据类型 没有“拷贝结构”的概念,因此不需要浅/深拷贝
2️⃣引用类型(Object、Array、Function 等)
-
引用类型 变量存的是“内存地址”(引用)
-
❗ 赋值或复制的是引用
-
所以有必要区分:
- 🟡 浅拷贝:复制第一层,嵌套引用共享,修改 可能会影响原本数据【若第一层为基本类型则不会影响】
- 🟢 深拷贝:彻底复制,修改 互不影响
⚠ 浅拷贝常见方式
| 方法 | 是否浅拷贝 |
|---|---|
Object.assign({}, obj) | ✅ 是 |
{ ...obj }(扩展运算符) | ✅ 是 |
Array.prototype.slice() | ✅ 是 |
Array.prototype.concat() | ✅ 是 |
✅ 深拷贝推荐方式
| 方法 | 特点 |
|---|---|
structuredClone(obj) | ✅ 原生支持、处理复杂数据结构【嵌套对象、数组、Map、Set、Date、TypedArray 等】(推荐) ,❌ 不支持函数、DOM 元素、循环引用里的函数 |
JSON.parse(JSON.stringify(obj)) | ⚠ 【缺点】简单但无法复制函数、undefined、循环引用 |
第三方库 lodash.cloneDeep() | ✅ 功能强大、可复制几乎所有类型 |
总结对比图:
| 比较点 | 浅拷贝 | 深拷贝 |
|---|---|---|
| 复制层级 | 只复制第一层 | 递归复制所有层级 |
| 引用对象 | 拷贝的是引用地址 | 拷贝的是实际值 |
| 原对象变化影响拷贝? | ✅ 可能有影响【第一层为基本类型,则不影响】 | ❌ 没影响 |