#39
深拷贝 & 浅拷贝
Champ2026.04.29 13:58created at 2026.04.29 13:58updated at 2026.04.29 13:58
0 次阅读

拷贝的内容
- 浅拷贝只拷贝第一层数据,对于值类型,拷贝值,对于引用类型,拷贝引用,因此修改浅拷贝的对象会意外修改原对象
- 深拷贝递归复制所有层级的数据。原对象和拷贝对象完全独立。
浅拷贝的实现方式
//浅拷贝的实现方式
//1.展开运算符
const original = { a: 1, b: { c: 2 },c:null,d:undefined };
const shallowCopy = { ...original };
shallowCopy.a = 100; // 修改基本类型,不影响原对象
shallowCopy.b.c = 200; // 修改深层对象,会影响原对象
console.log(original.b.c); // 200 (被改变了)
console.log(original.c); // null
console.log(original.d); // undefined
//2.Object.assign()
const original = { a: 1, b: { c: 2 },c:null,d:undefined };
const shallowCopy = Object.assign({}, original);
shallowCopy.b.c = 200;
console.log(original.b.c); // 200
console.log(original.c); // null
console.log(original.d); // undefined
//3.数组操作(slice(),concat(),Array.from())
const original = [1, { x: 10 }];
const shallowCopy = original.slice(); // 或者 [...original]
shallowCopy[1].x = 999;
console.log(original[1].x); // 999
//4.手动循环实现
function shallowCopy(obj) {
const result = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {//只保留自身属性(不要父类上的)
result[key] = obj[key];
}
}
return result;
}
深拷贝的实现方式
//1.Json.parse(Json.stringify(obj))
//局限性:1.无法复制特殊类型(Nah,undefined,Function,Symbol,regexp,Date,Map,
//Set,Infinity)2.无法处理循环引用(报错)
const original = {
a: 1,
b: { c: 2 },
d: [3, 4]
};
console.log(original);
console.log(JSON.stringify(original));
const deepCopy = JSON.parse(JSON.stringify(original));
console.log(deepCopy.b.c); //2
deepCopy.b.c = 200;
deepCopy.d[0] = 999;
console.log(deepCopy.b.c); //200
console.log(original.b.c); // 2 (未改变)
console.log(original.d[0]); // 3 (未改变)
//2.structuredClone()
const original = {
a: 1,
b: { c: 2 },
d: new Date(),
e: /regex/,
f: new Map([['key', 'value']])
};
const deepCopy = structuredClone(original);
console.log(deepCopy.d === original.d); // false (日期对象被复制)
console.log(deepCopy.f === original.f); // false (Map 被复制)
// 支持循环引用
original.self = original;
const copy2 = structuredClone(original); // 不会报错
//3.手动递归实现
function deepClone(obj, hash = new WeakMap()) {
// 处理 null 或非对象
if (obj === null || typeof obj !== 'object') return obj;
// 处理循环引用
if (hash.has(obj)) return hash.get(obj);
// 处理日期、正则等特殊对象
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if (obj instanceof Map) {
const mapCopy = new Map();
hash.set(obj, mapCopy);
for (let [k, v] of obj) {
mapCopy.set(deepClone(k, hash), deepClone(v, hash));
}
return mapCopy;
}
if (obj instanceof Set) {
const setCopy = new Set();
hash.set(obj, setCopy);
for (let v of obj) {
setCopy.add(deepClone(v, hash));
}
return setCopy;
}
// 处理数组和普通对象
const cloneObj = Array.isArray(obj) ? [] : {};
hash.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key], hash);
}
}
return cloneObj;
}