JS深拷贝与浅拷贝

一 深拷贝与浅拷贝基本定义

浅拷贝(浅克隆):直接将存储在栈中的值赋值给对应变量,如果是基本数据类型,则直接赋值对应的值,如果是引用类型,则赋值的是地址
深拷贝(深克隆):就是把数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。深拷贝,是拷贝对象各个层级的属性
 
深拷贝与浅拷贝区别:引用类型保存的是内存地址,浅克隆操作的其实是共同的内存,所以深克隆主要就是判断对象属性的变量类型,然后进行层层复制基本数据类型。 
 
1 浅拷贝的方式:
方式1:数据直接赋值;
方式2:展开运算符(...);
方式3:Object.assign()方法只能深拷贝对象第一层数据:
 let target = { a: 1, b: 2 };
  let source = { b: 4, c: 5, child: { name: 'liming' } };

  const returnedTarget = Object.assign(target, source);
  source.c = 6;
  source.child.name = 'zhangsan';
  console.log(returnedTarget, source);

2 深拷贝的方式:
方法1:JSON.stringify 和 JSON.parse
 1   function deepClone(obj) {
 2     let _obj = JSON.stringify(obj),
 3       objClone = JSON.parse(_obj);
 4     return objClone
 5   }
 6 
 7   let obj1 = {
 8     name: '李明',
 9     arrayList: [1, 2, [3, 4], 5],
10     child: {
11       name: '张三',
12       years: 4
13     }
14   };
15   let obj2 = deepClone(obj1);
16 
17   obj1.child.name = '小王';
18   obj1.arrayList[2][0] = 10;
19 
20   console.log(obj1, obj2);

方法2:通过递归方式自定义:

 1  function deepClone(obj) {
 2     let objClone = Array.isArray(obj) ? [] : {};
 3     if (obj && typeof obj === 'object') {
 4       for (key in obj) {
 5         if (obj.hasOwnProperty(key)) {
 6           if (obj[key] && typeof obj[key] === 'object') {
 7             objClone[key] = deepClone(obj[key]);
 8           } else {
 9             objClone[key] = obj[key];
10           }
11         }
12       }
13     }
14     return objClone;
15   }
16 
17   let obj1 = {
18     name: '李明',
19     arrayList: [1, 2, [3, 4], 5],
20     child: {
21       name: '张三',
22       years: 4
23     }
24   };
25   let obj2 = deepClone(obj1);
26 
27   obj1.child.name = '小王';
28   obj1.arrayList[2][0] = 10;
29 
30   console.log(obj1, obj2);

 

 总结:
JSON.parse(JSON.stringify(Obj))原理是通过将对象转化为字符串基本数据类型在进行赋值操作。该实现虽然简单但也有其弊端,具体可参考:https://blog.csdn.net/u013565133/article/details/102819929?utm_medium=distribute.pc_relevant.none-task-blog-title-1&spm=1001.2101.3001.4242

 

 二JS 深拷贝 vs 浅拷贝之堆栈池:js数据类型在堆栈中的区别

1 、栈(stack)堆(heap):

堆和栈其实是两种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。堆栈是个特殊的存储区,主要功能是暂时存放数据和地址
栈(Stack操作系统):由操作系统自动分配释放 ,存放函数的参数值和局部变量的值等。其操作方式类似于数据结构中的栈。简单的理解就是当定义一个变量的时候,计算机会在内存中开辟一块存储空间来存放这个变量的值,这块空间就叫做栈,然而栈中一般存放的是基本类型数据,栈的特点是先进后出(或后进先出)
 
堆(Heap操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。其实在堆中一般存放变量是一些对象类型

 

2、基本类型和引用类型

  基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。

  基本数据类型有Undefined、Null、Boolean、Number 和 String、BigInt、Symbol,它们是直接按值存放的,所以可以直接访问。

  引用类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。

  当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

 

 

 

 

 

 

posted @ 2020-10-14 11:05  TerryMin  阅读(325)  评论(0编辑  收藏  举报