【js】浅拷贝 || 深拷贝 引用类型复制解析

数据类型背书

  • 基本类型(如 number、string、boolean):按值存储和传递

  • 引用类型(如 object、array、function):按引用存储和传递

  • 当你将一个对象赋值给另一个变量时,实际上只是复制了指向该对象的引用,而不是对象本身的内容。

  • const obj = { name: "radar" };
    const copy = obj;
    
    copy.name = "raven";
    console.log(obj.name); //raven

浅拷贝

浅拷贝的主要问题是:对于嵌套对象或数组,修改副本中的嵌套结构会影响原始对象。这是因为嵌套对象的引用在原始对象和副本之间是共享的。

Object.assign()

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 序列化

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);

新的原生 API--structuredClone

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

总结

深拷贝比浅拷贝消耗更多资源,特别是对于大型、复杂的数据结构。因此如果需要完全独立的副本使用深拷贝,否则浅拷贝就可以了。

你可能感兴趣的:(js实用小组件diy,项目周边技术支撑性backup,javascript,前端,开发语言)