数据的深拷贝实现原理

戳蓝字"

Web前端严选

"

关注我们哦

1.数据的浅拷贝

let obj = {
    a: 1,
    b: 2,
    c: {
        d: 99
    }
};

若要拷贝当前obj,可以使用for循环依次复制其键值,也可以使用扩展运算符。

let newObj = {
    ...obj
};
newObj.c.d = 100;
console.log(obj); //{ a: 1, b: 2, c: { d: 100 } }

拷贝后的值应与旧值无关,若扔存在关联则是浅拷贝。这里对新值进行修改,旧值也发生了改变,表明在复制obj时,将c属性的对象引用地址也拷贝过去了,造成了新值对旧值的引用地址修改。

这里可以再看一下数组的操作:

let arr = [1, 2, 3, [4]]; 
let newArr = arr.slice(0)
newArr[3][0] = 100;

console.log(arr); //[ 1, 2, 3, [ 100 ] ]

通过slice方法将arr的值全部截取,并赋值给newArr。这里对新值的数组元素进行操作,也影响到了旧值,因此slice做到的是也是浅拷贝。

2.实现深拷贝

那么,我们如何实现深拷贝呢?

1.对当前数据类型进行校验

2.数据的循环引用问题

以上两点是数据深拷贝的实现思路,首先需要对数据的类型进行判断,常见的判断方法有:

  • typeof

  • Object.prototype.toString.call

  • instanceof

  • constructor

如果是基本数据类型(number,string,boolean,null,undefined)时,可以直接将值进行返回;

这里要提到null和undefined的类型校验,可参看视频内容。

如果是函数类型(function)时,可以直接将该函数返回,因为函数一般以调用为主,将函数转为字符串复制一遍再返回仍旧是这个函数;

如果是内置对象实例,则根据其类新建对应的对象返回即可;

例如:RegExp,Date等

如果是数组或对象等引用类型,则根据其构造函数新建对应的值返回即可。

({}).constructor    //[Function: Object]

([]).constructor //[Function: Array]

根据其构造函数可以直接new新值,创建新的值后,新值与旧值完全无关,这时通过循环旧值的索引或键,将值依次赋值到新值上去即可。

附方法源码:

function deepClone(value) { 
    if (value == undefined) return value;
    if (typeof value !== 'object') return value; 
    if (value instanceof RegExp) return new RegExp(value);
    if (value instanceof Date) return new Date(value);

    let instance = new value.constructor;
    for (let key in value) { 
        if (value.hasOwnProperty(key)) { //只拷贝私有属性
            instance[key] = deepClone(value[key]);
        }
    }
    return instance;
}

❤️ 感谢大家

如果你觉得这篇内容对你挺有有帮助的话:

  1. 点赞支持下吧,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)

  2. 关注公众号【Web前端严选】,定期为你推送好文。

添加个人微信,进群与小伙伴一起玩耍(已经推出)~

点个在看,大家都看 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值