• ES6的解构赋值与深拷贝和浅拷贝


    昨天工作之中,前端伙伴讨论到了解构赋值到底是浅拷贝还是深拷贝,今天梳理一下。

    1、ES6的解构赋值,大家应该都清楚,就是可以快速取出数组或者对象中的值;具体使用情况如下:

    const a = {
          name: 'name',
          age: 18,
          marriage: false,
        }
    
    let { name, age, marriage} = a;
    console.log(name, age, marriage) 
    打印信息:name 18 false

    2、明确一下深拷贝和浅拷贝的定义,或者说深拷贝和浅拷贝所应用于的数据类型。

    深拷贝:修改新变量的值不会影响原有变量的值。默认情况下基本数据类型(number,string,null,undefined,boolean)都是深拷贝。
    浅拷贝:修改新变量的值会影响原有的变量的值。默认情况下引用类型(object)都是浅拷贝。

    其实你只要理解透彻了这两句话就应该明白了解构赋值,甚至深拷贝的原理;

    写两个例子,理解一下深拷贝和浅拷贝;

    2.1 基本数据类型,直接用等号赋值,也都是深拷贝;

    let a = 1;
    let b = a;
    b = 2;
    console.log(a,b);
    打印出:1,2

    b的数值改变并不会影响a,所以基本数据类型赋值就是深拷贝;

    2.2 引用类型,直接用等号赋值,是浅拷贝;

    let a = {
        name: 'xiaoming'
    };
    let b = a;
    b.name = 'zhangsan';
    
    console.log(a)

    打印:

     发现a的数据被b改变,所以是浅拷贝,为什么数据会被改变呢?

    因为他们引用的是同一个地址的数据!拷贝的时候并没有给b创造独立的内存,只是把a指向数据的 指针 拷贝给了b!(不做延伸,感兴趣的同学自行百度)

    3、回到解构赋值,改一下最上面的例子。

    const a = {
          name: 'name',
          age: 18,
          marriage: false,
        }
    
    let { name, age, marriage} = a;
    
    name = 'name1';
    age = 20;
    marriage = true;
    console.log(a) 

    打印:

     发现a的数据并没有被改变,解构赋值好像是深拷贝啊?????

    我们再改一下上面的例子看看:

    const a = {
          name: 'name',
          age: 18,
          marriage: false,
          addr: { province: 'sichuan', city: 'chengdu' }
        }
    
    let { name, age, marriage, addr } = a
    
    name = 'myname'
    age = 26
    marriage = true
    addr.province = 'shanghai'
    addr.city = 'shanghai'
    
    console.log(name, age, marriage, addr) 
    console.log(a) 

    打印:

     发现解构赋值出来的对象将原对象a中的addr的数据修改了,这样看还是浅拷贝;

    总结:解构赋值,如果所解构的原对象是一维数组或对象,其本质就是对基本数据类型进行等号赋值,那它就是深拷贝;

    如果是多维数组或对象,其本质就是对引用类型数据进项等号赋值,那它就是浅拷贝;

    最终的结论就是:解构赋值是浅拷贝(因为它确实不能对多维数组或对象达到深拷贝的作用);

    4、最后我们再看一下深拷贝的本质:

    深拷贝的实现方法:

    function deepClone(source){
      const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
      for(let keys in source){ // 遍历目标
        if(source.hasOwnProperty(keys)){
          if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
            targetObj[keys] = source[keys].constructor === Array ? [] : {};
            targetObj[keys] = deepClone(source[keys]);
          }else{ // 如果不是,就直接赋值
            targetObj[keys] = source[keys];
          }
        }
      }
      return targetObj;
    }

    主要看这个:

    它的本质还是将对象拆开为基本数据类型进行赋值。

  • 相关阅读:
    CDH 下线节点
    Linux下如何查看哪些进程占用的CPU内存资源最多
    CentOS7安装iptables防火墙
    Mysql 编译报错 g++: internal compiler error: Killed (program cc1plus) 解决办法
    Jenkins配置gitlab
    mysql连接卡死,很多线程sleep状态,导致CPU中mysqld占用率极高
    c++0.1-----基于对象知识大综合(非指针篇)
    c++0.0-----挖坑
    python0.16------构造函数/析构函数/self详解/重写/访问限制/对象属性和类属性/@property/运算符重载
    python0.15-----继承和多态
  • 原文地址:https://www.cnblogs.com/blessYou/p/13038566.html
Copyright © 2020-2023  润新知