深拷贝的具体实现方式JS

深拷贝(Deep Copy)是指将一个对象的所有内容完整复制到另一个对象中,而不仅仅是复制对象的引用。也就是说,深拷贝不仅拷贝了对象本身,还会递归地拷贝对象内嵌的所有对象,避免原对象和拷贝对象共享引用。

实现深拷贝的一种常见方法是递归。具体步骤如下:

处理循环引用(拓展)(用这个就好了其他的写法忽略掉)

为避免循环引用导致的栈溢出,可以通过使用 Map 来跟踪已经拷贝过的对象。例如:

function deepCloneWithCycleCheck(obj, map = new Map()) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
// 如果已经拷贝过这个对象,则直接返回拷贝的对象,避免循环引用
if (map.has(obj)) {
return map.get(obj);
}
let copy = Array.isArray(obj) ? [] : {};
map.set(obj, copy);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCloneWithCycleCheck(obj[key], map);
}
}
return copy;
}

深拷贝实现的关键点:

  1. 递归调用:当对象内部存在嵌套对象时,需要对嵌套对象继续递归调用 deepClone 函数,确保每一层的对象都被复制。
  2. 类型判断:在拷贝过程中,必须首先判断当前值是否是对象或者数组,因为只有对象和数组才需要递归拷贝,而其他类型(如字符串、数字、布尔值等)直接赋值即可。
  3. 数组处理:对于数组,我们需要遍历数组的每一项,并对每一项进行深拷贝。
  4. 防止循环引用:这个实现没有处理循环引用问题,如果对象中存在循环引用(如对象的某个属性引用了对象本身),递归会导致栈溢出。为了解决这个问题,需要使用某种方式来追踪已经拷贝过的对象,通常可以借助一个 Map 或 WeakMap 来存储已经处理的对象。

例子

const original = {
name: "Alice",
age: 25,
details: {
city: "New York",
hobbies: ["reading", "cycling"]
}
};
const copied = deepClone(original);
// 修改复制对象的内容,验证原始对象不受影响
copied.details.city = "Los Angeles";
copied.details.hobbies.push("swimming");
console.log(original.details.city); // New York
console.log(original.details.hobbies); // ["reading", "cycling"]
console.log(copied.details.city); // Los Angeles
console.log(copied.details.hobbies); // ["reading", "cycling", "swimming"]

这样可以处理循环引用,确保深拷贝不会导致无限递归。

posted @   脆皮鸡  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示