浅拷贝与深拷贝

浅拷贝:

 正常复制一个对象,它们都是指向同一个内存地址,改变一个对象的属性另外一个也会跟着改变

 

我们新创建一个新的空对象,再把另外一个对象里的内容复制过来,这样它们就不会有关联了

 

 

1.什么是浅拷贝?

把数组/对象第一层的值, 复制到新的数组/对象中

2.浅拷贝使用场景?

修改数组/对象, 影响另一个数组/对象, “砍断”它们的联系

3.如何实现浅拷贝?

for/for...in/扩展运算符/Object.assign()对象用

 深拷贝:

如果一个对象里的值有多层的时候,这是浅拷贝只能拷贝第一层的值,第二层的值相互引用

 

 什么是深拷贝?

把数组/对象所有层的值, 复制到新的数组/对象中

如何实现深拷贝?

  1. 创建新数组/对象
  2. 判断基础类型, 直接赋值
  3. 判断对象类型, 递归调用函数, 继续创建判断
  4. 函数最终返回新数组/对象
        let oldObj = {
            name: "小明",
            age: 18,
            grade: [100, 90],
            family: {
                fName: "王"
            }
        }

        // 实现: 深拷贝
        // 注意: 先写Array类型的判断(因为Array的父类是Object, 写在上面无论数组对象都会进去)
        let newObj = {};
        function deepClone(newO, old){
            for (let key in old) {
                let value = old[key]
                if (value instanceof Array) {
                    newO[key] = [] // 被拷贝的是数组, 创建一个新数组
                    deepClone(newO[key], value)
                } else if (value instanceof Object) {
                    newO[key] = {} // 新对象
                    deepClone(newO[key], value)
                } else {
                    newO[key] = value; // 基础类型, 单纯值复制
                }
            }
        }
        deepClone(newObj, oldObj);
        oldObj.grade.push(600);
        console.log(newObj);

        // 总结: 深拷贝
        // 递归每层引用类型, 遇到对象/数组, 创建一个新的, 把基础值复制过来

深拷贝_循环引用问题解决

 let oneObj = {
            name: 'oneObj'
        }
        let twoObj = {
            name: "twoObj",
            age: 18,
            grade: [100, 90],
            family: oneObj // two引用one
        }

        // one引用two(造成循环引用-互相引用)
        oneObj.a = twoObj

       // 方案: ES6: Map集合结构
        // Map对象key可以是任意类型(对象类型)
        let newObj = {};
        function deepClone(newO, twoObj, map){ // {}, twoObj对象, oneObj对象
            if (!map) {
                map = new Map()
            }
            for (let key in twoObj) { // key: 'family'
                let value = twoObj[key] // value: oneObj对象, 读到a的时候, twoObj又进来了
                if (value instanceof Array) {
                    newO[key] = [] 
                    deepClone(newO[key], value)
                } else if (value instanceof Object) {
                    newO[key] = {} 
                    if (!map.has(value)) { // 如果这个对象在map里出现过, 就不要再进入递归拷贝了(防止无限递归)
                        map.set(value, 1) // map值: Map{ objObj对象: 1, twoObj对象: 1 }
                        deepClone(newO[key], value, map)
                    }
                } else {
                    newO[key] = value; 
                }
            }
        }
        deepClone(newObj, twoObj);
        console.log(newObj);

        // 总结:
        // 在递归的时候, 判断map集合中, 是否出现过这个值的对象
        // 没有出现过, 递归进入
        // 出现过了, 就留下一个空数组/空对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值