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,它们是直接按值存放的,所以可以直接访问。
引用类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。
当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。