深拷贝和浅拷贝

深浅拷贝

  1. 首先浅拷贝和深拷贝只针对想Object,Array这样的复杂对象,简单来说,浅拷贝只复制一层对象的属性,二深拷贝则复制了所有的层级。

  2. 对于字符串类型,浅复制是对值的复制,对于对象来说,浅复制是对对象地址的复制,并没 有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会 改变,而深复制则是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。

浅拷贝

  //1. 浅拷贝就是对象或数组中的值 不能拷贝复杂数据类型
    //  都是简单数据类型,就是个改个的 复杂数据类型改一个另一个也改变
    const obj1 = {}
    const obj2 = { name: '宇智波带土', age: 18, friends: ['琳'] }
    Object.assign(obj1, obj2) // obj2 的值 给obj1
    console.log(obj1)
    console.log(obj2)

    //修改对象中的简单数据类型 另一个不会发生改变
    obj1.name = '宇智波鼬'
    obj1.friends.push('班主任')
    console.log(obj1)
    console.log(obj2)

    //  拓展 数组里的浅拷贝
    const arr1 = [1, 2, 3].concat()
    console.log(arr1)
    const arr2 = [...arr1]
    console.log(arr2)

修改对象中的简单数据类型的值 另一个不会发生改变

修改复杂数据类型中的值 另一个也会跟着改变

所以这个时候就需要用到深拷贝

深拷贝

1.利用JSON深拷贝

   // 利用json中的方法,把一个对象转换成字符串 然后再将他解析成对象
    const obj1 = {name:'宇智波带土',age:18,friends:['旗木卡卡西']}


    // 利用JSON深拷贝
    const obj2 = JSON.parse(JSON.stringify(obj1))
    //修改一个值 另一个值不会改变
    obj1.name = '宇智波佐助'
    obj1.age = 25
    obj1.friends.push('火影鸣人')
    console.log(obj1)
    console.log(obj2)

         

 2.利用lodash中的_.cloneDeep进行深拷贝

 <!-- 引入lodash.min.js -->
  <script src="./lodash.min.js"></script>
  <script>
    //1.JSON.stringify()不识别函数
    const obj1 = {name:'宇智波带土',age:18,friends:['旗木卡卡西'],fn:()=> console.log(123)}

    console.log(JSON.stringify(obj1)) //得不到方法  不会解析函数

    // 想要识别函数 , 进行深层赋值 必须引入lodash.min.js
    // consol.log('_');  //引入lodash.min.js 就能够使用_ 这个变量 
    const obj2 = _.cloneDeep(obj1)
    console.log(obj1)
    console.log(obj2)
    obj1.name = '六道佩恩'
    obj1.friends.push = '小南'
    console.log(obj1)
    console.log(obj2)

 

3.利用递归进行深拷贝

// 1. 递归就是函数自己调用自己
    // 递归要有停止条件,否则就是死递归
    // 条件1 调出有条件
    // 条件2 跳出有条件

    //计数器
    let count = 0
    // 条件1 . 调用有条件 重要的事情说三遍
    function fn1() {
      console.log('重要的事情说三遍')
      count++
      if (count < 3) {
        fn1()  // 递归调用 满足条件就调用
      }
    }

    // fn1()

    //条件2  跳出有条件 重要的事情说三遍

    function fn2() {
      if (count >= 3) {
        return
      }
      console.log('重要的事情说三遍')
      count++
      fn2()
    }
    fn2()

 

封装递归方法

  <script>
    // 定理: 所有复杂数据类型 分析到最后 一定会是两种数据类型:函数 和 简单数据类型

    // 封装一个方法,实现深层复制 把obj2里面的各种属性值 复制到obj1里面去
    function cloneDeep(obj1, obj2) {
      for (let k in obj2) {
        //判断属性值的类型 Array Object  其他类型就可以当作简单类型操作
        // A instanceof B 的意思就是 A是否是B创建的
        //因为所有对象都是Object创建的 所以判断数组应该再判断对象之前
        if (obj2[k] instanceof Array) {
          obj1[k] = [] //设置OBJ1里面的相同属性为一个空数组
          cloneDeep(obj1[k], obj2[k]) //递归通过数组赋值
        } else if (obj2[k] instanceof Object) {
          obj1[k] = {} //设置OBJ1里面的相同属性为一个空对象
          cloneDeep(obj1[k], obj2[k]) //递归通过数组赋值
        } else {
          //如果只考虑浅拷贝 那么就可以使用for... in... 遍历obj2 然后让obj1里面也赋值一份
          obj1[k] = obj2[k];
        }
      }
    }
    const o1 = { name: '宇智波佐助', age: 18, friends: '旗木卡卡西', aaa: { a: 1, b: 2 } }
    const o2 = {}

    cloneDeep(o2, o1)
    console.log(o1)
    console.log(o2)

    //修改o1里面的属性
    o1.name = '宇智波带土'
    o1.age = 25
    o1.friends.push = '鸣人'
    console.log(o1)
    console.log(o2)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值