JS的深拷贝

// 顾名思义,深拷贝就是完完整整的将一个对象从内存中拷贝一份出来。所以无论用什么办法,必然绕不开开辟一块新
// 的内存空间。
// 通常有下面两种方法实现深拷贝:
// 1.迭代递归法
// 2.序列化反序列化法
// 我们会基于一个测试用例对常用的实现方法进行测试并对比优劣:
    let _ = require('lodash');
    let test = {
        num: 0,
        str: '',
        boolean: true,
        unf: undefined,
        nul: null,
        obj: {
            name: '我是一个对象',
            id: 1
        },
        arr: [0, 1, 2],
        func: function() {
            console.log('我是一个函数')
        },
        date: new Date(0),
        reg: new RegExp('/我是一个正则/ig'),
        err: new Error('我是一个错误')
    };
    
    let result = deepClone4(test);
    
    console.log(result);
    for (let key in result) {
        if (isObject(result[key]))
            console.log(`${key}相同吗? `, result[key] === test[key]);
    }
    
    //判断是否是对象
    function isObject(obj) {
        return (typeof obj === 'object' ||typeof obj === 'function') && obj !== null;
    }
    
    //一.迭代递归法:就是对对象进行迭代操作,对它的每个值进行递归深拷贝。
    //1.for...of...
    function deepClone(obj) {
        if (!isObject(obj)) {
            throwError('不是一个对象');
        }
        let re = Array.isArray(obj) ? [] : {};
        for (const key of Object.keys(obj)) {
            re[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key];
        }
        return re;
    } //arr 和 obj 都深拷贝成功了,它们的内存引用已经不同了,但 func、date、reg 和 err 并没有复制成功,
    //因为它们有特殊的构造函数。

在这里插入图片描述

//2.Reflect.ownKeys()
function deepClone2(obj) {
    if (!isObject(obj)) {
        throwError('不是一个对象');
    }
    let re = Array.isArray(obj) ? [] : {};
    Reflect.ownKeys(obj).forEach(key => {
        re[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key];
    });
    return re;
} //结果和前者一样

在这里插入图片描述

//3.lodash中的深拷贝
function deepClone3(obj) {
    return _.cloneDeep(obj);
} //arr、obj、date、reg深拷贝成功了,但 func 和 err 内存引用仍然不变。

在这里插入图片描述

    //二.序列化反序列化法:它先把代码序列化成数据,再反序列化回对象
    function  deepClone4(obj) {
        return JSON.parse(JSON.stringify(obj));
 }//它也只能深拷贝对象和数组,对于其他种类的对象,会失真。这种方法比较适合平常开发中使用,因为通常不需要考
// 虑对象和数组之外的类型。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值