浅拷贝和深拷贝区别----手写深拷贝代码

1. 浅拷贝深拷贝

狭义上的深浅拷贝只是针对引用数据类型而言的,基本数据类型只有赋值操作

  • 浅拷贝:只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存;修改拷贝后的数据对原数据有影响
    如果属性是基本类型,拷贝的就是基本类型的值;如果属性是引用类型,拷贝的就是内存地址

  • 深拷贝:开辟一块新的内存地址用于存放复制的对象,新对象和原对象不共享内存,修改新对象不会影响原对象

2. 浅拷贝实现方法

Object.assign

Object.assign({},obj):日常开发中常用的一种涉及‘深浅拷贝’的方式;
当obj是单层对象时,此时的Object.assign()能实现“深拷贝”;
而当obj为多层对象时,那么Object.assign({},obj)只能视为‘浅拷贝’

扩展运算符、slice、concat

和assign一样只拷贝一层

3. 深拷贝实现方法

JSON.stringify和JSON.parse

JSON.parse(JSON.stringify(xxx)):JSON 序列化,是日常工作中使用最多的,能解决大部分问题的方法。
这种组合能实现普通对象的深拷贝,而实现function,Symbol(),undefined、Date、RegExp这几种时,会造成数据丢失,原因是 JSON 不支持这些数据类型。

const obj={
    age:18,
    name:'zy',
    address:'changsha',
};
var result = JSON.parse(JSON.stringify(obj))
result.age=23;
console.log(obj) //{age: 18, name: 'zy', address: 'changsha'}
console.log(result) //{age: 23, name: 'zy', address: 'changsha'}
第三方库 lodash
lodash.cloneDeep(obj)

4. 深拷贝手写

主要实现思想:通过递归思维,遍历所需进行深拷贝的对象,直到里边的都是基本数据类型,然后再进行赋值,就是深度拷贝。

利用WeakMap / Map来解决循环引用的问题:解决循环引用的问题其实很简单,只需要在每次对复杂数据类型进行深拷贝前保存其值,如果下次又出现了该值,就不再进行拷贝,直接截止。

function deepClone(obj){
    //判断是不是对象
    if(typeof obj!=='object' || obj==null)  return obj;
    if(obj instanceof Date) return new Date(obj); //日期值
    if(obj instanceof RegExp) return new RegExp(obj); //正则
    //确定是数组还是对象
    let newObj = (obj instanceof Array) ? [] : {};

    //循环+递归
    for (let i in obj) {
        if(obj.hasOwnProperty(i)){
            newObj[i] = deepClone(obj[i]);
        }
    }
    return newObj;
}
const newObj = deepClone(obj)
newObj.address.school='ahu'
console.log(newObj)
console.log(obj)
//解决循环引用
function deepClone(obj, map=new WeakMap()){
    if(typeof obj!=='object' || obj==null)  return obj; //判断是不是对象
    if(obj instanceof Date) return new Date(obj); //日期值
    if(obj instanceof RegExp) return new RegExp(obj); //正则
    let newObj = (obj instanceof Array) ? [] : {};
    //let newObj = new obj.constructor() //创建一个和obj类型一样的对象

    if(map.get(obj)) return map.get(obj); //防止循环引用
    map.set(obj,newObj);//放入缓存中

    //循环+递归
    for (let i in obj) {
        if(obj.hasOwnProperty(i)){
            newObj[i] = deepClone(obj[i],map);
        }
    }
    return newObj;
}

const obj = {
    age:18,
    address:{
    school:'csu'
 },
} 
obj.info = obj
let newObj = deepClone(obj)
console.log(newObj)
console.log(newObj.address === obj.address)  //false
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值