基本类型(如 number、string、boolean):按值存储和传递
引用类型(如 object、array、function):按引用存储和传递
当你将一个对象赋值给另一个变量时,实际上只是复制了指向该对象的引用,而不是对象本身的内容。
const obj = { name: "radar" };
const copy = obj;
copy.name = "raven";
console.log(obj.name); //raven
浅拷贝的主要问题是:对于嵌套对象或数组,修改副本中的嵌套结构会影响原始对象。这是因为嵌套对象的引用在原始对象和副本之间是共享的。
const original = { name: "ra", details: { age: 30 } };
const shallowCopy = Object.assign({}, original);
shallowCopy.name = "re"; // 不影响原对象
shallowCopy.details.age = 25; // 影响原对象!
console.log(original.name); // 输出: "ra"
console.log(original.details.age); // 输出: 25
const original = { name: "John", details: { age: 30 } };
const shallowCopy = { ...original };
// 行为与 Object.assign() 相同
// 使用 slice()
const originalArray = [1, 2, { value: 3 }];
const slicedArray = originalArray.slice();
// 使用展开运算符
const spreadArray = [...originalArray];
// 使用 Array.from()
const fromArray = Array.from(originalArray);
// 所有这些方法都只创建浅拷贝
slicedArray[2].value = 100;
console.log(originalArray[2].value); // 输出: 100
JSON.stringify 处理成字符串格式再JSON.parse还原
but:不能复制函数、undefined、Symbol、BigInt; 不能处理循环引用; 丢失原型链; 不能正确处理 Date、RegExp、Map、Set 等特殊对象
const original = { name: "John", details: { age: 30 } };
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.details.age = 25;
console.log(original.details.age); // 输出: 30,原对象不受影响
自定义递归
function deepclone(obj) {
if (obj === null || typeof obj !== "object") {
return obj;
}
// 处理 Date
if (obj instanceof Date) {
return new Date(obj.getTime()
}
// 处理 Arrayif
if(Array.isArray(obj)) {
return obj.map(item => deepClone(item))
};
//处理 Object
const clonedobj = {};
Object.keys(obj).forEach( key => {
clonedobj[key] = deepcone(obj [key]);
});
return clonedobj;
}
const original = { name: "John", details: { age: 30 }};
const deepCopy = deepClone(original);
deepCopy.details.age = 25;
console.log(original.details.age); // 输出: 30
but: 实际应用时,需要按照具体情况加很多处理方法~
lodash _.cloneDeep();
const newObj = _.cloneDeep(obj);
but:不能克隆函数和DOM,也不能保留原型链
const obj = {
name: "ra",
details: { desc: 'yyds'},
dates: [new Date()],
map: new Map([["key", "value"]])
}
const clone = structuredClone(obj);
clone.details.desc="newDesc";
console.log(obj.details.desc)
//yyds
深拷贝比浅拷贝消耗更多资源,特别是对于大型、复杂的数据结构。因此如果需要完全独立的副本使用深拷贝,否则浅拷贝就可以了。