深克隆与浅克隆详解
什么是深拷贝与浅拷贝
浅拷贝:只复制对象的基本类型,对于引用类型,只是克隆地址(包含的内嵌的对象或数组,不再复制副本)
引用类型,只是克隆地址,那么原对象修改,克隆后的新对象也会跟着变化,克隆不彻底
数组的 Array.from() 方法就是实现的浅拷贝
对象的 Object.assign() 方法也是实现的浅拷贝
浅拷贝的代码实现
function lowClone(val) {
var newObj = {}
for (var key in val) {
newObj[key] = val[key]
}
return newObj
}
var obj = {
a: 1,
b: [2, 3, [4]],
c: { c1: 5 }
}
var result = lowClone(obj)
// 用JSON.Stringify方便看打印结果
console.log(JSON.stringify(result)) //{"a":1,"b":[2,3,[4]],"c":{"c1":5}}
obj.c.c1 = 7;
obj.b[2] = [5, 6]
console.log(JSON.stringify(obj)) //{"a":1,"b":[2,3,[5,6]],"c":{"c1":7}}
console.log(JSON.stringify(result)) //{"a":1,"b":[2,3,[5,6]],"c":{"c1":7}}
// 可以看出浅克隆的原对象改变,克隆后的对象属性也跟着改变,浅克隆只是克隆地址。
深拷贝:复制对象的基本类型和引用类型(包含的内嵌的对象或数组,依然复制副本)
深拷贝的代码实现
实现深拷贝需要用到递归的思想
具体代码如下:
// 实现深拷贝
function deepClone(val) {
//判断是普通类型或是null直接返回
if (typeof val !== 'object' || val === null) {
return val
}
//判断是array
if (val instanceof Array) {
return val.slice()
}
//判断是对象
var newObj = {}
for (var key in val) {
// Object的hasOwnProperty()方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性。
if (val.hasOwnProperty(key)) {
// 递归调用
newObj[key] = deepClone(val[key])
}
}
return newObj
}
var obj = {
a: 1,
b: [2, 3, [4]],
c: { c1: 5 }
}
var result = deepClone(obj);
// 用JSON.Stringify方便看打印结果
console.log(JSON.stringify(obj)) //{"a":1,"b":[2,3,[4]],"c":{"c1":5}}
console.log(JSON.stringify(result)) //{"a":1,"b":[2,3,[4]],"c":{"c1":5}}
obj.c.c1 = 7;
obj.b[2] = [5, 6]
console.log(JSON.stringify(obj)) //{"a":1,"b":[2,3,[5,6]],"c":{"c1":7}}
console.log(JSON.stringify(result)) //{"a":1,"b":[2,3,[4]],"c":{"c1":5}}
附另外两种写法
function deepClone( obj ){
let objClone = Array.isArray(obj) ? [] : {};
if( obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
let a=[1,2,[2, 3],4],
b=deepClone(a);
a[2][0]=10;
console.log(a,b);
function deepClone(obj){
let _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone
}
let a=[0,1,[2,3],4],
b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
————————————————
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通