码迷,mamicode.com
首页 > Web开发 > 详细

JS 深浅拷贝的区别以及实现方式

时间:2020-05-25 17:21:29      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:就是   类型   引用类型   基本   efi   spl   object   one   big   

在学习JS时最让我头疼的就是栈和堆以及一切概念性的问题 也是最近才把想给这个搞通提上了日程

简单来说 深浅拷贝的区别:

   A复制了B 当改变 A 中的一个元素 B 中的这个元素也改变了 这就叫做浅拷贝

  反之 改变 A 中的元素 B 中的元素并没有一起改变 这就叫做 深拷贝  深拷贝都是针对于较为复杂的object类型

  这个也就要牵扯到栈和堆 以及 数据类型的概念了

  JS几大基本数据类型: Null Undefined Number Boolean String Object Symbol(唯一值) BigInt(ES10未来 任意精度整数)

  引用类型:Object类 --- 常规名值对的无序对象{a: 1} 数组:[1, 2] 函数等

  1、基本类型 --- 名值都储存再栈内存中; let a = 1

    技术图片

 

 

   当 b = a 复制时; 栈内存会新开辟一个内存

  技术图片

 

 

   所以当你修改 a = 2 时 b 的值并不会发生改变  但这也算不上深拷贝 因为深拷贝都是针对于较为复杂的object类型

  2、引用类型 名存栈内存中 值存堆内存中 但是栈内存会提供一个引用地址指向堆内存中的值

  技术图片

 

  所以当 a = b 进行拷贝的时候 复制的是 a 的引用地址 而非堆里面的值

 

   技术图片

  当我们 a [0] = 7 时 由于 a 和 b 指向的都是同一个堆内存值 所以 a 的修改 影响到了 b  这就是所谓的浅拷贝

  技术图片

 

 

   所以要实现深拷贝 就是要在堆内存中新建一个 b 的堆内存

  技术图片

 

  实现深拷贝

  function deepClone(obj){

    let a = JSON.stringify(obj);

    b = JSON.parse(a)

    return b 

  }

  let a = [0, 1, [3,4], 9]

  b = deepClone(a)

  a[2][0] = 7

  console.log(a, b) //[0,1,[7,4],9] [0, 1, [3,4], 9]

  

  JSON.stringify() 和 JSON.parse() 的区别

  JSON.stringify() 将对象转换为 JSON字符串 而 JSON.parse() 则是将JSON字符串转换为 对象

  但是在使用JSON.parse()时   所转换的JSON字符串必须要符合JOSN格式 即键值都需要 "" 进行包裹

 

 let a = ‘["1","2"]‘;
 let b = "[‘1‘,‘2‘]";
 console.log(JSON.parse(a));// Array [1,2]
 console.log(JSON.parse(b));// 报错
  技术图片

 

   递归方式实现:

  

function deepClone(obj){
  let objClone = Array.isArray(obj)?[]:{};
  if(obj && typeof obj==="object"){
    for(key in obj){
      if(obj.hasOwnProperty(key)){
      //判断ojb子元素是否为对象,如果是,递归复制
        if(obj[key]&&typeof obj[key] ==="object"){
          objClone[key] = deepClone(obj[key]);
  }else{
    //如果不是,简单复制
    objClone[key] = obj[key];
          }
        }
      }
    }
    return objClone;
  }
  let a=[1,2,3,4],
  b=deepClone(a);
  a[0]=2;
  console.log(a,b);

技术图片

 

 

   

  数组放 splice  concat slice 都不是真正的深拷贝 在一级层级是没问题的 当有二层层级时  就会被影响

  let a=[1,2,3,4],
      b=a.slice();
  a[0]=2;
  console.log(a,b);
技术图片

 


 

  let a=[0,1,[2,3],4],
          b=a.slice();
  a[0]=1;   a[2][0]=1;   console.log(a,b);

 


 技术图片

 

 

 

 

JS 深浅拷贝的区别以及实现方式

标签:就是   类型   引用类型   基本   efi   spl   object   one   big   

原文地址:https://www.cnblogs.com/qlb-7/p/12957968.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!