深克隆与浅克隆详解

什么是深拷贝与浅拷贝

浅拷贝:只复制对象的基本类型,对于引用类型,只是克隆地址(包含的内嵌的对象或数组,不再复制副本)
引用类型,只是克隆地址,那么原对象修改,克隆后的新对象也会跟着变化,克隆不彻底
数组的 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);


————————————————

posted @   好命先生w  阅读(265)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示