• 深拷贝学习笔记


    在开发过程中,我碰到了一个问题,让我找了好久问题在哪里,最后我发现是最开始赋值的时候没有深拷贝值,导致了原本值被覆盖污染,这里和大家分享下我的解决方法

    var i = 5;
    
    var j = i;
    
    j=1;
    
    console.log(i);//5
    
    console.log(j);//1
    

      

    我们正常赋值的逻辑是像上面一样,复制一份下来,然后对复制的那一份进行操作,这样的逻辑是对的,但是这样的拷贝默认是浅拷贝,当出现以下情况时,这种写法就会出问题

    var i = {
    
            value:5
    
    };
    
    var j = i;
    
    j.value=1;
    
    console.log(i.value);//1
    
    console.log(j.value);//1
    

      

    是不是觉得很奇怪,我在网上找了一下为什么,是有关浅拷贝和深拷贝的知识:

    (浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针,出现深浅拷贝的情况是当对象为Object或Array时才会出现。)

    我分享下我的三种种解决方法:

    第一种,使用JSON.parse(JSON.stringify())

    let arr = [1, 3, {
    
        username: ' kobe'
    
    }];
    
    let arr4 = JSON.parse(JSON.stringify(arr));
    
    arr4[2].username = 'duncan';
    
    console.log(arr, arr4)
    

      

    原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。

    第二种:Object.assign()

    var obj = { a: {a: "kobe", b: 39} };
    
    var initalObj = Object.assign({}, obj);
    
    initalObj.a.a = "wade";
    
    console.log(obj.a.a); //wade
    

      

    Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

    但是 Object.assign()进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

    第三种:手写递归方法

    递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝

    function getType(obj) {
      //tostring会返回对应不同的标签的构造函数
      var toString = Object.prototype.toString;
      var map = {
        '[object Boolean]': 'boolean',
        '[object Number]': 'number',
        '[object String]': 'string',
        '[object Function]': 'function',
        '[object Array]': 'array',
        '[object Date]': 'date',
        '[object RegExp]': 'regExp',
        '[object Undefined]': 'undefined',
        '[object Null]': 'null',
        '[object Object]': 'object'
      };
      if (obj instanceof Element) {
        return 'element';
      }
      return map[toString.call(obj)];
    }
    
    
    //深拷贝
     function deepClone(data) {
      var type = getType(data);
      var obj;
      if (type === 'array') {
        obj = [];
      } else if (type === 'object') {
        obj = {};
      } else {
      //不再具有下一层次
        return data;
      }
      if (type === 'array') {
        for (var i = 0, len = data.length; i < len; i++) {
          obj.push(deepClone(data[i]));
        }
      } else if (type === 'object') {
        for (var key in data) {
          obj[key] = deepClone(data[key]);
        }
      }
      return obj;
    }

    如果大家有其他方法,也欢迎在下面分享ヽ( ̄▽ ̄)ノ

  • 相关阅读:
    【35】单层卷积网络(simple convolution)
    【34】三维卷积
    【33】卷积步长讲解(Strided convolutions)
    【32】Padding(填充)原理讲解
    【31】更多的边缘检测方法
    08-----pymysql模块使用
    07-----多表查询
    06-----单表查询
    05-----数据的增删改
    04-----外键的变种 三种关系
  • 原文地址:https://www.cnblogs.com/smileZAZ/p/13657357.html
Copyright © 2020-2023  润新知