1. 浅拷贝
浅拷贝(Shallow Copy)是指创建一个新对象,仅复制原始对象的第一层属性。若属性是基本类型(如数字、字符串),直接复制值;若属性是引用类型(如对象、数组),则复制内存地址引用(新旧对象共享嵌套数据)
特点
- 修改原始对象的
基本类型属性不会影响拷贝后的对象 - 修改原始对象的
引用类型属性(数组元素、对象属性)会影响拷贝后的对象
const original = { a: 1, b: { c: 2 } };
const copy = { ...original };
copy.b.c = 100;
console.log(original.b.c); // 输出 100(原对象被修改!)
实现方式
- 使用
Object.assign方法
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };
- 使用对象的扩展运算符
{...}
const shallowCopy = Object.assign({}, obj);
- 使用
slice、concat方法
const arr = [1, [2, 3]];
const arrCopy = arr.slice();
2. 深拷贝
深拷贝(Deep Copy)是指递归复制对象的所有层级属性,完全创建新的内存空间。新旧对象的所有属性(包括嵌套引用类型)完全独立。
特点
无论修改原始对象的任何属性,拷贝后的对象都不会受到影响
实现方式
- 使用
JSON.parse(JSON.stringify())
const deepCopy = JSON.parse(JSON.stringify(obj));
- 缺点:丢失函数、
undefined、Symbol、Date对象(转为字符串)、无法处理循环引用。
- 使用
structuredClone()(现代浏览器原生方法)
const deepCopy = structuredClone(obj);
- 缺点:仍不支持函数、DOM节点。
- 使用Lodash的
cloneDeep
import _ from 'lodash';
const deepCopy = _.cloneDeep(obj);
3.手写浅拷贝与深拷贝
手写浅拷贝
function shallowCopy(target) {
// 处理非对象类型(直接返回)
if (typeof target !== 'object' || target === null) {
return target;
}
// 创建新容器(数组或普通对象)
const copy = Array.isArray(target) ? [] : {};
// 遍历并复制第一层属性
for (const key in target) {
if (target.hasOwnProperty(key)) {
copy[key] = target[key]; // 直接赋值(引用类型共享地址)
}
}
return copy;
}
手写深拷贝
function deepClone(target, map = new WeakMap()) {
// 基本类型直接返回
if (target === null || typeof target !== 'object') {
return target;
}
// 处理循环引用(避免无限递归)
if (map.has(target)) {
return map.get(target);
}
// 处理特殊对象类型
const constructor = target.constructor;
if (/^(Date|RegExp)$/i.test(constructor.name)) {
return new constructor(target); // 创建新实例
}
// 初始化克隆对象
const clone = Array.isArray(target) ? [] : {};
map.set(target, clone); // 记录已拷贝对象
// 复制Symbol类型属性
const symKeys = Object.getOwnPropertySymbols(target);
symKeys.forEach((symKey) => {
clone[symKey] = deepClone(target[symKey], map);
});
// 递归复制所有属性
for (const key in target) {
if (target.hasOwnProperty(key)) {
clone[key] = deepClone(target[key], map);
}
}
return clone;
}
4. 总结
| 特性 | 浅拷贝 (Shallow Copy) | 深拷贝 (Deep Copy) |
|---|---|---|
| 对象独立性 | 新对象与原始对象共享嵌套引用 | 新对象完全独立于原始对象 |
| 性能 | 较快(只复制顶层结构) | 较慢(递归复制所有嵌套对象) |
| 适用场景 | 简单对象或不需要修改嵌套数据时 | 需要完全独立的副本,尤其是嵌套结构时 |
| 内存占用 | 较低(共享引用) | 较高(完全复制) |