递归深拷贝

107 阅读2分钟

浅拷贝深拷贝之理解及应⽤场景

⾸先,浅拷贝和深拷贝都是只针对于像Object,Array这样的复杂对象。

区别:浅拷贝只复制对象的第⼀层属性、深拷贝可以对对象的属性进⾏递归复制

  • 理解

1、浅拷贝:简单的说,浅拷贝就是增加了⼀个指针指向已存在的内存(JavaScript并没有指针的概念,这⾥只是⽤于辅助说明),钱凯被只是拷贝了内存地址,⼦类的属性指向的是⽗类属性的内存地址,当⼦类的属性修改后,⽗类的属性也随之被修改。 2、深拷贝:深拷贝就是增加⼀个指针,并申请⼀个新的内存,并且让这个新增加的指针指向这个新的内存地址使⽤深拷贝,在释放内存的时候就不会像浅拷贝⼀样出现释放同⼀段内存的错误,当我们需要复制原对象但有不能修改原对象的时候,深拷贝就是⼀个,也是唯⼀的选择。

  • 应⽤场景

1:从服务器fetch到数据之后我将其存放在store中,通过props传递给界⾯,然后需要对这堆数据进⾏修改,那涉及到的修改就⼀定有保存和取消,所以我们需要将这堆数据拷贝到其它地⽅。

2:当你想使⽤某个对象的值,在修改时不想修改原对象,那么可以⽤深拷贝弄⼀个新的内存对象。像es6的新增⽅法都是深拷贝,所以推荐使⽤es6语法。

  • 代码示例
//定义对象obj1内容
      var obj1 = {
        name : '张三',
        age : 20
      }
      //递归深拷贝
      function surAtt(obj1){
        //判断obj1是数组还是对象,根据obj1不同的传入选择对应的
        var obj2 = Object.prototype.toString.call(obj1) === "[Object Array]"?[]:{}
        for (let key in obj1){
            if (obj1.hasOwnProperty(key)) {
                // typeof判断是否是多重对象
                if(typeof obj1[key] === 'object'){
                    // 如果是多重对象递归函数继续调用
                    obj2[key] = surAtt(obj1[key])
                }else{
                    obj2[key] = obj1[key]
                }
            }
            return obj2
        }
      }
      
    //   把obj1里面的属性赋值给obj2修改obj2里面的属性是否对obj1里面的属性有影响
      var obj2 = surAtt(obj1)
      console.log(obj2)
      obj2.name = "李四"
      console.log(obj1)